Jea*_*ond 21 c++ time timezone date dst
我正在创建一个应该适用于多个时区的c ++项目.应用程序接收带有参考时区的事件,并在当地时区以正确的小时以图形方式向用户显示此事件.例如,在柏林工作的用户收到在东京写的活动.来自东京的事件首先在UTC时间转换,然后从UTC重新转换为柏林的计算机当地时间,最后在他的图形界面上向用户显示.
要将UTC转换为本地计算机时间,我可以使用Windows API的多个功能来完成这项工作.但是为了将时间从另一个时区转换为UTC,我需要从Windows注册表中获取时区信息.
现在一些时区也需要考虑夏令时.我可以毫无问题地从Windows信息创建重复规则.但是我注意到DST应该发生的那天有时候在几个时区都是不正确的.例如,"E.南美标准时间".随着Windows提供的重复发生,DST开始日期提前1周开始.
如果我理解正确,Windows为此特定时区返回的重复规则表示"每年,第2个月,在该月的第2周".但是,此规则很少与互联网上发布的更改时间的正确日期相匹配,而如果规则是"每年,第2个月,在该月的第3周",则日期都是正确的.此外,正如您在提供的屏幕截图中看到的那样,Windows注册表数据显示DST开始时间为2周(以蓝色突出显示),但DST结束时间为3周(以红色显示),这是由我的代码正确计算的.可以在此处找到数据内容的描述:http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v = vs.85).aspx
我有几个问题
注意我在发布此消息之前已经强烈验证了我从注册表中读取的数据是否正确.我很确定这不是这种类型的错误.
注意我正在使用Windows 7,但问题在Windows 10上保持不变
Mat*_*int 65
作为一名重要参与Windows时区数据的Microsoft员工,请允许我向您保证Microsoft非常努力地确保其发布更新以使Windows时区数据保持尽可能准确.
有几个挑战,包括政府给出的时区变化时间.例如,我们最近发布了关于斐济,塞浦路斯,苏丹,汤加,纳米比亚和特克斯和凯科斯群岛即将进行的Windows时区变更的通知.在某些情况下,我们可以满足这些不同政府制定的生效日期.在某些情况下,我们不能,因为他们没有提供足够的准备时间.
考虑最近苏丹的案例,该案件于2017年10月17日告知IANA tz邮件列表2017年 11月1 日生效的更改.IANA已处理此更改,Microsoft也是如此.但由于通知时间短,以及在Windows操作系统中处理此类更改所需的"Sudan Standard Time"时间,在Windows时区数据中创建新时区之前还需要一段时间.因此,我们发布临时指南以暂时使用不同的时区,然后在我们拥有能够正确反映受影响地区的完整时间历史的数据后再切换回来.
对于您提到的Windows时区"E. South America Standard Time",时区数据是正确的.如果展开注册表项,您将看到有一个名为"Dynamic DST"的子键,其中包含对数据的逐年更改.对于某些时区,这根本不是必需的,对于其他时区,您会发现非常少量的数据,因为相同的规则年复一年地重复.但就巴西而言,您会注意到2009年至2040年的动态DST条目.
(单击图像查看完整分辨率,并注意我手动标记为红色的区域逐年变化)
Dynamic DST条目支持Win32 DYNAMIC_TIME_ZONE_INFORMATION结构,以及名称中带有"dynamic"的相应API,例如GetDynamicTimeZoneInformation.(它们也支持System.TimeZoneInfo.NET Framework中的类.)自Windows Vista/Server 2008以来,大多数这些API已经存在,而其他一些API则出现在Windows 7/Server 2012中.
请注意,TZI内部Windows进程会从当前年份的动态规则中复制父键中的条目.这支持与Win32 TIME_ZONE_INFORMATION结构一起使用的API ,这些结构自Windows 2000以来就已经存在.
要回答您提出的具体问题:
我是否正确理解了重复规则?
你提到的具体规则仅适用于2017年,和它说,DST 结束的第2个月(2月)的第三个星期六,23:59:59.999本地时间,并在第10个月重新开始(10月),上第二个星期六,当地时间23:59:59.999.请记住,巴西位于南半球,因此夏令时开始于年底,并在明年年初结束.
此外,你可能想知道为什么周六23:59:59.999而不是周日00:00:00000.这是历史的一件神器.在过去,某些程序和过程错误地使用<=而不是<评估转换,因此会意外地将时钟移动到第二天一毫秒,退出它,然后再次返回它.错误地改变一天所产生的事件可能会导致进一步的问题.微软已尽最大努力修复这些错误,但仍然选择关闭1毫秒,而不是冒一个新地方出现问题的风险.(这仅适用于恰好在午夜发生的转换.)
是否存在关于多个时区的已知问题,尤其是"E.南美标准时间"?
该时区没有已知问题,但是存在一个已知问题,即Windows时区(即使使用动态DST数据)在一年内最多只能支持两个时区转换.因此,在像摩洛哥这样每年过渡四次的地方,有一些内部解决方法可以使当前时区数据保持同步,以便"现在"是当地时间的准确表示,但不能正确表示年份中的所有点在任何给定的时间.
我们目前还没有一个时区可以清楚地映射到南极洲的Troll Station.原因是从2005年到2015年,这个研究站(50岁以下的人口)每年都通过三种不同的偏移(UTC + 0,UTC + 1和UTC + 2)进行过渡.
如果您的应用程序严重依赖于上述任一方案,那么我建议使用带有IANA数据源的API而不是Win32 API.
有没有理由为什么DST开始日期,显然每年定期发生,在第10个月的第3周,在第2周设定值?
是的,如上所述,这是由于1ms的故意错误.2017年夏令时,在巴西有DST的地区,于10月15日周日00:00:00000开始.那是本月的第三个星期天.1ms之前是10月14日星期六23:59:59.999,也就是这个月的第二个星期六.这可能每年都不同,这就是动态DST数据的原因.
在Windows注册表中写入的时区是否可靠,如果没有,我应该使用Windows API的哪个功能来转换带有DST的时区,而不是使用与本地计算机上设置的时区不同的时区编写的日期?
如果您使用的是Win32 API,则它们自己使用注册表数据,因此无需直接使用注册表数据.您应该更喜欢API的"动态"版本,因为它们正确地考虑了动态DST数据中的逐年变化.有时这些被标记为"Ex".例如,您询问的函数最好由TzSpecificLocalTimeToSystemTimeEx函数处理.
...
尽管如此,如果您能够避免在应用程序中使用Windows时区数据,我建议您这样做.首选IANA数据源或源自它们的数据源.使用IANA时区数据的路线很多.较新的Windows API,如Windows.Globalization.Calendar和Windows.Globalization.DatetimeFormatting.DateTimeFormatter在WinRT中/ UWP确实使用IANA时区,这显然是前进的道路.在标准的C++空间中,我强烈建议使用Howard Hinnant的date/tz库,或者ICU项目提供的库.还有其他几个可行的选择.
| 归档时间: |
|
| 查看次数: |
3806 次 |
| 最近记录: |