date/时间转换问题,如果时刻恰好在冬季结束(非DST)

在我的应用程序中,我需要使用文件中描述的模式来计算偏移。 最近,由于以下原因,我的客户之一的应用程序被挂起:

如果你在冬天结束时(非DST)填写'struct tm',_mktime似乎会返回一个不正确的结果。

代码如下所示:

struct tm tm_start; tm_start.tm_mday = startday; tm_start.tm_mon = startmonth-1; tm_start.tm_year = startyear-1900; tm_start.tm_hour = starthour; tm_start.tm_min = startmin; tm_start.tm_sec = startsec; tm_start.tm_isdst = -1; // Don't know if DST is active at this moment _int64 contTime = _mktime64(&tm_start); 

假设4月5日凌晨2:00从冬季到夏季转换。 实际上,这意味着我们有以下几个时刻:

 5 April, 1:58 5 April, 1:59 5 April, 3:00 

由于我不知道在DST开始或结束时的应用程序(我真的想知道这个吗?)我使用上面显示的代码将date“5月4日,2:00”传递给_mktime64。

我期望_mktime64给我的time_t值,对应于4月5日,3:00(这是4月5日,2:00是完全相同的时刻)。

但是,这不是发生了什么事情。 _mktime64将tm_start更改为4月5日的1:00,并返回相应的time_t值。 这意味着我得到一个完全不同的时刻。 (实际上:2:00到3:00之间的每一刻都会导致_mktime64在1:00到2:00之间返回一个片刻)

我以为这是Visual Studio 2005中的一个错误,但显然Visual Studio 2010(Release Candidate)具有相同的行为。

这个问题出现在XP和Windows7上(没有检查Vista)。

这是一个已知的错误? 还是有其他技巧来解决这个问题?

我想它根本不知道如何正确处理你通过的无效时间。而且这对你所在的时区来说肯定是无效的 – 你把它想成“冬天1:59后1分钟”,这意味着你希望它能在DST恢复运行时返回“3:00”,这听起来很合理。 然而,它也可以把它当作“夏天3点前的一个小时”,意思是它一定是从冬天开始的,因此返回“1点”。 因此,我不认为这是一个错误 – 它更可能是未定义的行为,如何处理一个不存在的时间。

我期望最安全的方法是全面使用UTC,因此没有歧义。 显然,这可能不会干净地映射到您的应用程序领域,但这是推迟时间的黑暗世界!

这是使用本地时间而不是UTC工作的必然结果。 DST的结束也是一个愚蠢的行为,时间戳在转换过程中是矛盾的,因为当地时间匹配两次。

这很容易通过使用UTC来解决,这就是操作系统所做的。 检查你的CRT实现,像_gmtime64()或原生的GetFileTime()。

试图将4月5日2:30转换为time_t类似于将2011年2月29日转换为time_t 。 在任何情况下,你都不期望有效的结果,因为输入不是有效的日期。 4月5日,甚至2点不存在。 1:59.59之后是3:00:00