Как на результат функции Delphi NOW влияет опция «Настроить часы для перехода на летнее время» - PullRequest
4 голосов
/ 12 января 2011

Я понимаю, что на этот вопрос можно было бы ответить, написав тестовый код. Я не ленивый, я просто подумал, что ответ может быть в целом полезным.

У меня есть приложение, которое сгенерировало большой объем данных с записями, которые были отмечены местным временем (как возвращено подпрограммой NOW). Мы столкнулись с препятствиями, связанными с переходами в летнее время и из него, а именно в том, что при переходе на летнее время пропускается час, а при выходе из летнего времени повторяется час. Это вызывает проблемы с манипуляциями, предполагающими дату упорядоченных записей.

Приложение было изменено для работы со всеми датами в UTC, но у меня будет возможность отображать даты в UTC или по местному времени. Я также должен разобраться с датами, которые были сохранены по местному времени, и убедиться, что они правильно переведены на UTC. Это сложно, так как дата и время могли быть сохранены во время действия DST, поэтому в общем случае мне необходимо определить, находится ли какая-либо случайная дата в пределах или вне периода DST. Конечно, существует период в один час, когда дата и время неоднозначны и могут быть в последний час до окончания летнего времени или в первый час после его окончания. Нет способа решить это.

При кодировании изменений я задавался вопросом о результате звонков NOW. Внутренне это вызывает GetLocalTime. Что возвращает GetLocalTime (и СЕЙЧАС), когда вы находитесь в период перехода на летнее время, но опция «Настроить часы для изменения летнего времени» отключена?

Как мне написать подпрограмму, которая возвращает текущую дату и время в течение периода летнего времени (с примененным смещением летнего времени) независимо от того, включено или выключено «Настроить часы для изменения летнего времени»?

Ответы [ 2 ]

4 голосов
/ 12 января 2011

Не думаю, что вы можете легко решить вашу проблему.
Слишком много переменных:

  • сохраненная временная метка
  • часовой пояс, в котором вы находитесь
  • постоянно меняющиеся правила часовых поясов
  • подтверждение того, что эти правила часовых поясов точны на всем оборудовании, которое вы используете (т. Е. Каждый всегда применяет свои патчи)
  • неточность ваших часов

Существует проект Delphi TZDB , который может помочь вам с правилами о часовых поясах.

Я думаю, что гораздо практичнее не полагаться на все вышеперечисленноепеременные, но хранят три поля:

  • метка времени в местном формате
  • текущий часовой пояс
  • метка времени в формате UTC

Вы выполняете сортировку по третьему полю и первым двум полям для отображения.

- jeroen

2 голосов
/ 12 января 2011

Используйте TzSpecificLocalTimeToSystemTime (и его очевидное обратное).Они позволяют вам конвертировать между UTC и местной датой / временем на основе настроек летнего времени, действующих на местную дату / время.Если вы хотите, чтобы ваше приложение работало на чем-то более раннем, чем XP, загрузите его (из kernel32) с атрибутом функции 'delayed':

function TzSpecificLocalTimeToSystemTime(lpTimeZoneInformation: PTimeZoneInformation;
  var lpLocalTime, lpUniversalTime: TSystemTime): BOOL; stdcall;

function TzSpecificLocalTimeToSystemTime; external kernel32 name 'TzSpecificLocalTimeToSystemTime' delayed;
...