Проблема преобразования даты / времени, если момент точно в конце Wintertime (не DST)

StackOverflow https://stackoverflow.com/questions/2378492

Вопрос

В моем приложении мне нужно рассчитать сдвиги, используя шаблон, описанный в файле. В последнее время у одного из моих клиентов приложение висит из-за следующей причины:

Если вы заполните «структуру 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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top