С++ mktime и летнее время

Я обрабатываю сохраненные даты и время. Я храню их в файле по Гринвичу в строковом формате (т.е. DDMMYYYYHHMMSS). Когда клиент запрашивает, я преобразовываю эту строку в struct tm, а затем преобразовываю ее в секунды, используя mktime. Я делаю это, чтобы проверить недопустимый DateTime. Я снова конвертирую секунды в строковый формат. Вся эта обработка в порядке, никаких проблем вообще.

Но у меня есть одна странная проблема: я сохранил дату и время по Гринвичу с локалью также по Гринвичу. Из-за перехода на летнее время мое местное время изменилось на GMT+1. Теперь, если я запрашиваю сохраненную дату и время, я получаю на 1 час меньше, потому что функция mktime использует локаль, то есть GMT+1, для преобразования struct tm в секунды (tm_isdst устанавливается на -1, поэтому mktime автоматически определяет переход на летнее время и т. д.).

Любые идеи, как решить эту проблему?


person user2409054    schedule 21.03.2014    source источник


Ответы (3)


Используйте _mkgmtime/timegm в качестве дополнения к mktime.

time_t mkgmtime(struct tm* tm)
{
#if defined(_WIN32)
   return _mkgmtime(tm);
#elif defined(linux)
   return timegm(tm);
#endif
}
person dalle    schedule 21.03.2014
comment
Спасибо за ваш ответ, это может решить проблему. На данный момент везде, где mktime используется для операций с датами, но мне придется добавить новую функцию, чтобы использовать mkgmtime для этой конкретной цели. - person user2409054; 21.03.2014

Флаг перехода на летнее время (tm_isdst) больше нуля, если действует летнее время, ноль, если летнее время не действует, и меньше нуля, если информация недоступна.

http://www.cplusplus.com/reference/ctime/tm/

person JefGli    schedule 21.03.2014
comment
Моя программа будет использоваться в разных частях мира, поэтому для tm_isdst установлено значение -1, поэтому mktime автоматически определяет переход на летнее время. - person user2409054; 21.03.2014

Вот общий алгоритм:

  1. Передайте свой ввод mktime.
  2. Передайте вывод gmtime.
  3. Передайте вывод mktime.

А вот пример кода:

struct tm  input  = Convert(input_string); // don't forget to set 'tm_isdst' here
time_t     temp1  = mktime(&input);
struct tm* temp2  = gmtime(&temp1);
time_t     output = mktime(temp2);

Обратите внимание, что функция gmtime не ориентирована на многопотоковое исполнение, поскольку она возвращает адрес static struct tm.

person barak manos    schedule 21.03.2014