Непонятное поведение mktime в Linux? - PullRequest
5 голосов
/ 16 сентября 2011

Я использую функцию mktime (struct tm *) в Suse 10.

Теперь я замечаю странное поведение, когда летнее время включено. Допустим, я включил переход на летнее время, чтобы он начался 15 сентября в 18:10, а коррекция на летнее время - на 30 минут. Теперь, когда я вызываю mktime со структурой tm, имеющей дату как 15 сентября 18:10, и tm_isdst установлен в 0, я получаю те же значения в структуре tm только с tm_isdst, установленным в 1.

Но, если передать дату как 15 сентября 18:10 с tm_isdst, установленным в 1, то я найду, что время изменилось на 17:40. Это исправление в структуре tm замечено за время, прошедшее между 15 сентября 18:10 и 15 сентября 18:40, но после этого никакого исправления во времени не происходит, и флаг dst остается активным. Даже если я передаю дату как 16 сентября 18:10, коррекция времени не происходит, только флаг dst остается активным.

Я полностью сбит с толку. Это правильное поведение mktime?

Ответы [ 2 ]

6 голосов
/ 25 сентября 2011

Если местное время изменяется на 30 минут для перехода на летнее время, то один раз в год происходит 30 минут местного времени, которые происходят дважды (один раз с переходом на летнее время и один раз без), и еще 30 минут, когда происходит никогда (оно пропускается, когда время меняется).

Таким образом, местное время в течение 30 минут после установки часов неоднозначно, если не указано, действует ли DST;Есть два фактических момента времени, которым они могут соответствовать.

Местное время в течение 30 минут с момента, когда часы установлены заранее, недействительно;нет фактических моментов времени, которым они могли бы соответствовать (хотя преобразование могло бы все еще быть сделано, предполагая, что летнее время действует, или не действует).

Так для некоторых локальных времен (игнорируя состояние летнего времени)может быть более одного соответствующего времени UTC, но для любого данного времени UTC есть только одно возможное местное время (если корректировки DST учтены должным образом).

Когда вы звоните mktime, это преобразовывает местноевремя, которое вы даете ему time_t, как если бы DST действовал или нет, в зависимости от значения tm_isdst.Исправленные значения, которые вы получите, основаны на обратном преобразовании, и система определит, получите ли вы время DST или время не-DST, в зависимости от ее представления о том, действует ли DST во время преобразования.Время, которое вы дали, и время, которое вы вернули, фактически представляют один и тот же момент времени, но с различными смещениями от UTC из-за различных состояний летнего времени.

Так что да, это правильное поведение mktime,Предполагается, что она нормализует значения в структуре в соответствии с ее идеей о том, как правильно представлять время, которое вы ей дали.

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

0 голосов
/ 16 сентября 2011

Проверьте этот ответ и посмотрите, поможет ли это. Кроме того, каково смещение часового пояса системы? Проверьте, запустив:

date +%z
...