_mktime64是否正确处理历史DST规则?

时间:2019-01-03 09:19:08

标签: c++ windows dst crt

我正在使用_mktime64函数将本地时间转换为UTC(在Windows计算机上)。 _mktime64函数的输入可以是过去和将来的日期。 似乎该函数始终使用执行时有效的当前DST规则,而不使用任何历史规则(Windows上存在!)。 我正在寻找这种情况的确认。

在美国,DST规则似乎在2007年发生了变化(例如,参见https://en.wikipedia.org/wiki/Eastern_Time_Zone)。 因此,在2007年之前,东部时区的夏令时开始于4月的第一个星期日凌晨2点。 从2007年开始,东部时区的夏令时开始于3月的第二个星期日凌晨2点。

2003年4月的第一个星期日是6月6日,因此DST应该在这一天开始。

现在,东部时区与UTC的时差在标准时间是-5小时,在夏令时是-4小时。

因此,当将2003年4月1日转换为UTC时,由于DST尚未开始,我预计会相差5小时。 将2008年4月1日转换为UTC时,由于DST已于当年开始,因此我预计会相差4小时。

但是,看来2003年4月1日的结果不正确。

从MSDN文档(https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/mktime-mktime32-mktime64?view=vs-2017)中,我可以读到它试图从TZ env确定DST信息。变量或通过GetTimeZoneInformation函数。 我没有TZ env变量,因此我假设它使用GetTimeZoneInformation函数。该函数的文档(https://docs.microsoft.com/en-us/windows/desktop/api/timezoneapi/nf-timezoneapi-gettimezoneinformation)似乎提到它返回“当前时区设置”。 这对我来说还不清楚。我应该将其解释为当前的DST规则吗?或者,当前在我的计算机上配置的所有时区规则? 这似乎意味着“当前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;
   }

0 个答案:

没有答案