Преобразование между локальными временами и GMT/UTC в C/С++
Какой лучший способ конвертировать datetime между локальным временем и UTC в C/С++?
В "datetime" я имею в виду некоторое представление времени, которое содержит дату и время суток. Я буду рад time_t
, struct tm
или любому другому представлению, которое делает это возможным.
Моя платформа - Linux.
Вот конкретная проблема, которую я пытаюсь решить: я получаю пару значений, содержащих юлианскую дату и количество секунд в день. Эти значения указаны в GMT. Мне нужно преобразовать это значение в локальный часовой пояс "YYYYMMDDHHMMSS". Я знаю, как преобразовать юлианскую дату в Y-M-D, и, очевидно, легко конвертировать секунды в HHMMSS. Однако сложной частью является преобразование часового пояса. Я уверен, что смогу найти решение, но я предпочел бы найти "стандартный" или "известный" способ, а не спотыкаться.
Возможно, связанный с этим вопрос: Получить даты перехода на летнее время для временных зон в C
Ответы
Ответ 1
Предполагается использовать комбинации gmtime
/localtime
и timegm
/mktime
. Это должно дать вам ортогональные инструменты для выполнения преобразований между struct tm
и time_t
.
Для UTC/GMT:
time_t t;
struct tm tm;
struct tm * tmp;
...
t = timegm(&tm);
...
tmp = gmtime(t);
Для локального времени:
t = mktime(&tm);
...
tmp = localtime(t);
Все tzset()
устанавливает внутреннюю переменную часового пояса из переменной среды TZ
. Я не думаю, что это должно быть вызвано более одного раза.
Если вы пытаетесь преобразовать время между часами, вы должны изменить struct tm
tm_gmtoff
.
Ответ 2
Если в 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);
или что-то подобное...
Ответ 3
Если вам нужно беспокоиться о преобразовании даты/времени с правилами часового пояса, вы можете посмотреть в ICU.