Благодаря много, идеално, но... Великото НО
Вината е моя. Трябваше малко повечко да напиша по проблема.
Програмата Х чете и записва данни които са в формат TFileTime (структура, която съдържа брой единица от 100 наносекунди след 1 януари 1601 година), които не са локални за приложението (т.е. тези данни се четат от други програми, в повечето случаи на трети разработчици), а и по други причини, които по-надолу ще отбележа, така че не може а и не трябва да се използа TDateTime при запазването и четенето им, и "показва" времето по Coordinated Universal Time (UTC).
Например, ако днес сме 14 май 2005 14:00 часа, UTC е 14 май 2005 11:00 часа (Лятно време е), а GMT е равно на UTC+1.
Ако локалната дата (БГ), е 14 януари 2005 14:00 часа, UTC е 14 януари 2005 12:00 часа, (Зимно време е ) и GMT е равно на UTC.
Идеята е, хипотетично, използвайки данните запазени в UTC, например във всички времеви зони да бъдат изтруляни по 2 ракети насочени към слънцето. Така че, ако ние сме създателите на програмата, разпространявайки нашият файл с данни, където датата и часа са в UTC, ние няма да се съобразяваме с местното време, а ще сме сигурни че в точен, глобален, момент, събитието (изтрелването на ракетите) ще бъде изпълнено (ако котка път не мине) например в 14 часа BG време.
До тук добре.
Има си системни функции, които превръщат TFileTime в локалното време (LocalFileTime). Проблемът е че те не взимат в предвид Лятното и Зимното часово време, и кога то е въведено.
Един пример:
Нека датата е 14.5.2005 14:00 (местно БГ време)
procedure TForm1.Button1Click(Sender: TObject);
var
LocalFileTime, FileTime:TFileTime;
SystemTime:TSystemTime;
LocalDateTime, DateTime:TDateTime;
TempString:string;
begin
// установяваме местната дата и час
LocalDateTime:=StrToDateTime('14.5.2005 14:00');
// превръщаме го в SystemTime
DateTimeToSystemTime(LocalDateTime,SystemTime);
// превръщаме SystemTime до FileTime
SystemTimeToFileTime(SystemTime,LocalFileTime);
// цялата дивотия с горните две функции бе, че единствената функция предоставяна
// която превръща Локалното време в UTC, е LocalFileTimeToFileTime
// а тя пък използва FileTime структурата
LocalFileTimeToFileTime(LocalFileTime, FileTime);
// хайде обратно към системно време - за да визуализираме резултата
FileTimeToSystemTime(FileTime, SystemTime);
// още едно преубразуване
DateTime:=SystemTimeToDateTime(SystemTime);
// а стига де...
TempString:=DateTimeToStr(DateTime);
// най - накрая
ShowMessage(TempString);
// това което имаме в TempString е 14.5.2005 11:00
end;
Ако в горния пример заменим 14.5.2005 14:00 с 14.1.2005 14:00 (месеца е януари - зимно време), би трябвало да получим като краен резултат 14.1.2005 12:00
Но както казваше Петко Бочаров - Да ама не... Показва си 14.1.2005 11:00. Тоест не се взима в предвид лятно/зимно време (коректната стойност би трябвало да е 14.1.2005 12:00)..
Ето обратната функция от UTC към Местно (локално време), която не отчита
зимно/лятно време...
procedure TForm1.Button3Click(Sender: TObject);
var
LocalFileTime, UTCFileTime:TFileTime;
SystemTime:TSystemTime;
LocalDateTime, UTCDateTime:TDateTime;
TempString:string;
begin
UTCDateTime:=StrToDateTime('14.5.2005 11:00');
DateTimeToSystemTime(UTCDateTime,SystemTime);
SystemTimeToFileTime(SystemTime,UTCFileTime);
FileTimeToLocalFileTime(UTCFileTime, LocalFileTime);
FileTimeToSystemTime(LocalFileTime, SystemTime);
LocalDateTime:=SystemTimeToDateTime(SystemTime);
TempString:=DateTimeToStr(LocalDateTime);
ShowMessage(TempString);
end;
Също така, не би трябвало да се конвертира стойността 27.3.2005 03:00:01 местно, БГ време (примерно). Защото в България такъв час няма. След 27.3.2005 02:59:59, следваща стойност която би трябвало да може да се въвежда е 27.3.2005 04:00:00.
Отгоре на това DaylightDate в TIME_ZONE_INFORMATION връща датата и часа когато се преминава от Зимно в Лятно време за текущата година. И нищо по въпроса за предходно или бъдеще време. Така че мога да използвам за GetTimeZoneInformation за текущата година, и да направя необходимите корекции, но ако потребителя въведе например, че ракетите трябва да се изтрелят на 26.3.2006 в 03:00:01 местно БГ време (следващата година, ще се смени зимно с лятно в 3 часа на 26 март), какво става?!?
Такъв час няма!
Та такива ми ти работи....
|