Проблема преобразования даты / времени, если момент точно в конце Wintertime (не DST)
Вопрос
В моем приложении мне нужно рассчитать сдвиги, используя шаблон, описанный в файле. В последнее время у одного из моих клиентов приложение висит из-за следующей причины:
Если вы заполните «структуру TM» с точным моментом в конце Wintertime (не DST) _MKTime, кажется, возвращает неверный результат.
Код выглядит так:
struct tm tm_start;
tm_start.tm_mday = startday;
tm_start.tm_mon = startmonth-1;
tm_start.tm_year = startyear-1900;
tm_start.tm_hour = starthour;
tm_start.tm_min = startmin;
tm_start.tm_sec = startsec;
tm_start.tm_isdst = -1; // Don't know if DST is active at this moment
_int64 contTime = _mktime64(&tm_start);
Предположим, что есть выключатель от зимы - на летнее время 5 апреля в 2:00. На практике это означает, что у нас есть следующие моменты времени:
5 April, 1:58
5 April, 1:59
5 April, 3:00
Поскольку я не знаю в приложении, когда DST запускается или заканчивается (я действительно хочу знать это?) Я передаю дату 5 апреля, 2:00 "до _mktime64, используя код, показанный выше.
Я ожидал _mktime64, чтобы дать мне значение time_t, которое соответствует 5 апреля, 3:00 (который точно в тот же момент, как 5 апреля, 2:00).
Однако это не то, что происходит. _mktime64 Изменяет TM_START до 5 апреля, 1:00 и возвращает соответствующее значение time_t. Это означает, что я получаю совершенно другой момент. (На самом деле: каждый момент с 2:00 до 3:00 вызывает _mktime64, чтобы вернуться в минуту между 1:00 и 2:00)
Я думал, что это был ошибка в Visual Studio 2005, но, по-видимому, Visual Studio 2010 (кандидат выпуска) имеет то же поведение.
Проблема появляется на XP и Windows7 (не проверяла Vista).
Это известная ошибка? Или есть другие советы, чтобы решить эту проблему?
Решение
Я думаю, что это просто не знает, как правильно обрабатывать неверное время, которое вы проходите. И это, безусловно, недействительно для вашего часового пояса - вы думаете об этом как «1 минута после 1:59 зимой», подразумевая, что вы Хотел, чтобы он вернулся на «3:00» с DST обратно в эксплуатацию, что звучит разумно. Однако это может оно одинаково хорошо относиться к этому как «час до 3:00 летом», что он должен был быть из зимнего периода и, таким образом, возвращает «1:00». Таким образом, я не думаю, что это ошибка - это более вероятно, будет неопределенное поведение о том, как справиться с несуществующим временем.
Я ожидаю, что самый безопасный способ подходить к этому - использовать UTC на протяжении всего, как тогда нет неявок. Очевидно, что это может не отображать чисто к вашему прикладной домену, но таков мутный мир толкания времени назад и вперед!
Другие советы
Это неизбежное следствие работы по местному времени вместо UTC. Конец DST - это доой тоже, метки времени амбивалентны во время переключения, так как локальное время совпадает с двумя разами.
Это легко решается, работая с UTC вместо этого, это то, что работает операционная система. Проверьте свою реализацию CRT, что-то вроде _GMTIME64 () или нативный GetFileTime ().
Пытаясь конвертировать 5 апреля, 2:30 до time_t
похож на попытки преобразовать 29 февраля 2011 года на time_t
. Отказ В одном случае вы не ожидаете действительного результата, потому что вход не является действительной датой. 5 апреля, даже 2:00 не существует. 1: 59.59 сопровождается прямо к 3:00:00