Преобразование между локальным временем и GMT / UTC в C / C++

каков наилучший способ преобразования времени между локальным временем и UTC в C / C++?

под "datetime" я имею в виду некоторое представление времени, содержащее дату и время суток. Я буду счастлив с time_t, struct tm или любое другое представление, которое делает это возможным.

моя платформа-Linux.

вот конкретная проблема, которую я пытаюсь решить: я получаю пару значений, содержащих дату Джулиана и несколько секунд в день. Эти значения находятся в GMT. Мне нужно преобразовать это в значение локального часового пояса "YYYYMMDDHHMMSS". Я знаю, как преобразовать юлианскую дату в Y-M-D, и, очевидно, легко преобразовать секунды в HHMMSS. Тем не менее, сложная часть-преобразование часового пояса. Я уверен, что смогу найти решение, но я бы предпочел найти "стандартный" или "хорошо известный" способ, а не спотыкаться.


возможно вопрос получите даты перехода на летнее время для часовых поясов в C

3 ответов


вы должны использовать комбинации gmtime/localtime и timegm/mktime. Это должно дать вам ортогональные инструменты для преобразования между struct tm и time_t.

по Гринвичу/по Гринвичу:

time_t t;
struct tm tm;
struct tm * tmp;
...
t = timegm(&tm);
...
tmp = gmtime(t);

для получения локального времени:

t = mktime(&tm);
...
tmp = localtime(t);

все tzset() does устанавливает внутреннюю переменную часового пояса из TZ переменные среды. Я не думаю, что это должно называться больше одного раза.

если вы пытаетесь конвертировать между часовыми поясами вы должны изменить struct tm ' s tm_gmtoff.


Если в Windows у вас нет timegm (), доступного вам:

struct tm *tptr;
time_t secs, local_secs, gmt_secs;
time( &secs );  // Current time in GMT
// Remember that localtime/gmtime overwrite same location
tptr = localtime( &secs );
local_secs = mktime( tptr );
tptr = gmtime( &secs );
gmt_secs = mktime( tptr );
long diff_secs = long(local_secs - gmt_secs);

или что-то подобное...


Если вам нужно беспокоиться о преобразовании даты / времени с правилами часового пояса, вы можете посмотреть в ICU.