Я пытаюсь кодировать текущее время utc в строку с помощью функции strftime
:
time_t now;
struct tm nowLocal;
struct tm nowUtc;
now = time(NULL);
localtime_r(&now, &nowLocal);
gmtime_r(&now, &nowUtc);
Пока все хорошо: nowLocal
содержит текущее время в моем часовом поясе (CET), nowUtc
содержит время utc, разница точно соответствует значению tm_gmtoff
:
nowLocal: {tm_sec = 28, tm_min = 27, tm_hour = 13, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 1, tm_gmtoff = 7200, tm_zone = 0x8127a38 "CEST"}
nowUtc: {tm_sec = 28, tm_min = 27, tm_hour = 11, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 0, tm_gmtoff = 0, tm_zone = 0x3e9907 "GMT"}
Затем я вызываю strftime()
в формате "%s"
, чтобы получить секунды с эпохи:
char tsFromLocal[32];
char tsFromUtc[32];
strftime(tsFromLocal, sizeof(tsFromLocal), "%s", &nowLocal);
strftime(tsFromUtc, sizeof(tsFromUtc), "%s", &nowUtc);
Результат мне кажется странным. Я ожидал получить точно такую же строку из обоих вызовов strftime()
, поскольку формат %s
описывается как:
Количество секунд с начала эпохи, т. Е. С 1970-01-01 00:00:00 UTC
. Високосные секунды не учитываются, если не доступна поддержка дополнительных секунд.
Но у меня два разных значения:
tsFromLocal:"1337772448"
tsFromUtc: "1337768848"
и, кроме того, разница не 7200 (tm_gmtoff
), а 3600. Кто-нибудь может объяснить такое поведение? Или это ошибка?
Причина, по которой я это делаю, заключается в том, что мне нужно передать значение времени по сети и сравнить его с текущим временем на целевой машине, которая может находиться в другом часовом поясе. На целевой машине я хотел:
struct tm restoredUtc;
time_t restored;
strptime(tsFromUtc, "%s", &restoredUtc);
restored = timegm(&restoredUtc);
Но я получил:
restoredUtc:{tm_sec = 28, tm_min = 27, tm_hour = 12, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 1, tm_gmtoff = 7200, tm_zone = 0x8127a38 "CEST"}
Так что strptime()
в любом случае устанавливает tm_zone
в соответствии с текущим часовым поясом. Но даже если бы я использовал timelocal()
вместо timegm()
, я не получу правильного значения, поскольку оно должно быть 11:27:28 CEST, а не 12: 27:28 CEST. Связана ли эта ошибка с разными результатами strftime()
?
Есть какие-нибудь комментарии к этой более поздней части?
strftime()
интерпретирует прошедшую временную структуру как МЕСТНОЕ ВРЕМЯ. Вы получаете разницу в 1 час, потому что исходная структураnowLocal
имеетtm_isdst = 1
(установлено предыдущим вызовом localtime_r ()). Если вы установите для этого поля значение 0 перед вызовом strftime, вы, вероятно, получите ожидаемую разницу в 2 часа. - person Claudix   schedule 03.08.2012time()
, вы можете сравнить его с тем, что возвращаетstrftime()
, чтобы определить, какой из ответов правильный (если любой из них). Я предполагаю, что местное время правильное, а UTC - неправильное. Можно ли затем заставитьstrftime()
работать так, как вы хотите, за исключением установки переменной TZ наUTC0
и последующего вызоваtzset()
, открыто для обсуждения. - person Jonathan Leffler   schedule 17.03.2013