mktime не соответствует часовому поясу Австралии?

Я хочу создать struct tm с часовым поясом Australia/Sydney, поэтому сначала использую:

setenv("TZ","Australia/Sydney",1);
tzset()

затем я установил struct tm как:

struct tm _tm;
_tm.tm_sec = 0;
_tm.tm_min = 45;
_tm.tm_hour = 7;
_tm.tm_mday = 18;
_tm.tm_mon = 8;
_tm.tm_year = 114;

Это должно быть время Австралии 2014/09/18 7:45:00, затем я звоню:

time_t other_tm = mktime(&_tm);

После этого звонка other_tm и _tm указали на 6:45 утра по австралийскому времени! Причина в том, что other_tm имеет значение 1410986700, которое вы можете проверить с помощью конвертера Epoc, оно действительно указывает на 6:45 утра, кто-нибудь знает, почему?


person user2426361    schedule 18.09.2014    source источник
comment
Взгляните на преобразование UTC: stackoverflow.com/a/3661129/3895252   -  person Billy_Bob    schedule 18.09.2014
comment
stackoverflow.com/questions/10533322/mktime-and-tm -isdst-флаг   -  person n. 1.8e9-where's-my-share m.    schedule 18.09.2014
comment
setenv и tzset служат цели, используя правильный часовой пояс, чтобы mktime мог использовать текущий местный часовой пояс. Но это, кажется, не сработало.   -  person user2426361    schedule 18.09.2014
comment
@user2426361 user2426361 как насчет того, чтобы установить tm_isdst на что-то неслучайное, это сработало?   -  person n. 1.8e9-where's-my-share m.    schedule 18.09.2014
comment
@н.м. Да, я пропустил эту часть, извините. Да, набор tm_isdst = -1 сработал. Итак, мораль этой истории в том, что setenv недостаточно, мне нужно установить этот флаг на -1, чтобы mktime попытался выяснить, находится ли dst в местном часовом поясе. Спасибо.   -  person user2426361    schedule 18.09.2014


Ответы (1)


Используя эту кроссплатформенную бесплатную библиотеку с открытым исходным кодом на основе C++11/14 <chrono>, здесь современный способ получить желаемый результат:

#include "tz.h"
#include <iostream>

int
main()
{
    using namespace std::chrono_literals;
    using namespace date;
    auto zt = make_zoned("Australia/Sydney", local_days{2014_y/9/18} + 7h + 45min);
    std::cout << zt.get_sys_time().time_since_epoch().count() << '\n';
}

Это выводит:

1410990300

(то есть 1410986700 + 3600)

Эта библиотека намного проще и безопаснее в использовании, чем устаревший C API для обработки времени.

person Howard Hinnant    schedule 21.07.2016