Я использую функцию _mktime64 для преобразования местного времени в UTC (на машине с Windows).
Входными данными для функции _mktime64 могут быть как прошлые, так и будущие даты.
Кажется, что функция всегда использует текущие правила DST, которые действуют во время выполнения, а не какие-либо исторические правила (которые присутствуют в окнах!).
Я ищу подтверждение того, что это так.
В США, похоже, правила DST изменились в 2007 году (см., Например, https://en.wikipedia.org/wiki/Eastern_Time_Zone).
Поэтому до 2007 года летнее время в восточном часовом поясе начинается в первое воскресенье апреля в 2 часа ночи.
В то время как с 2007 года летнее время в восточном часовом поясе начинается во второе воскресенье марта в 2 часа ночи.
Первое воскресенье апреля 2003 года было 6-го, так что это будет день, когда должно начаться летнее время.
Теперь разница во времени между восточным часовым поясом и UTC составляет -5 часов по стандартному времени и -4 часа по летнему времени.
Итак, при преобразовании 1 апреля 2003 года в UTC я ожидаю разницу в 5 часов, так как летнее время еще не началось.
При преобразовании 1 апреля 2008 года в UTC я ожидаю разницу в 4 часа, так как летнее время уже началось в этом году.
Однако, похоже, что результат за 1 апреля 2003 года неверен.
Из документа MSDN (https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/mktime-mktime32-mktime64?view=vs-2017)) я могу прочитать, что он пытается определить информацию о летнем времени из переменной TZ env. Или через функцию GetTimeZoneInformation.
У меня нет переменной TZ env, поэтому я предполагаю, что она использует функцию GetTimeZoneInformation. Документ (https://docs.microsoft.com/en-us/windows/desktop/api/timezoneapi/nf-timezoneapi-gettimezoneinformation) для этой функции, похоже, упоминает, что она возвращает «текущие настройки часового пояса»).
Здесь мне становится немного неясно. Должен ли я интерпретировать это как текущие правила DST? Или все правила часового пояса, который сейчас настроен на моей машине?
Кажется, это означает «текущие правила перехода на летнее время», но я хотел бы получить подтверждение.
#include <iostream>
#include <time.h>
int main()
{
std::tm tmStruct;
std::tm *tmStructPtr;
__time64_t res;
// running on a machine in Eastern Time Zone
std::cout << std::endl << "april 1 2003 00:00:00" << std::endl;
tmStruct.tm_mday = 1;
tmStruct.tm_mon = 3; // april
tmStruct.tm_year = 103; // 2003
tmStruct.tm_hour = 0;
tmStruct.tm_min = 0;
tmStruct.tm_sec = 0;
tmStruct.tm_isdst = -1; // don't know, figure it out yourself
res = _mktime64(&tmStruct);
std::cout << res << std::endl;
tmStructPtr = _gmtime64(&res);
std::cout << tmStructPtr->tm_hour << std::endl; // prints out 4 while DST should not have started yet!
std::cout << std::endl << "april 1 2008 00:00:00" << std::endl;
tmStruct.tm_mday = 1;
tmStruct.tm_mon = 3; // april
tmStruct.tm_year = 108; // 2008
tmStruct.tm_hour = 0;
tmStruct.tm_min = 0;
tmStruct.tm_sec = 0;
tmStruct.tm_isdst = -1; // don't know, figure it out yourself
res = _mktime64(&tmStruct);
std::cout << res << std::endl;
tmStructPtr = _gmtime64(&res);
std::cout << tmStructPtr->tm_hour << std::endl; // prints out 4 = ok
return 0;
}