.NET 4.5中的TimeZoneInfo bug

3

我最近更新了我的操作系统,使用了 .net 4.5 框架并编译了所有应用程序。不幸的是,我写的一些自动化测试现在在关于 DateTime 类型的 Assert 结构上失败了。

经过深入分析,我发现了以下问题:

在 .net 4.0 中,

DateTime dateUsing40 = new DateTime(2011, 4, 7); // ticks 634377312000000000    
dateUsing40.ToUniversalTime(); //ticks **634377240000000000

bool isDaylightST = dateUsing40.IsDaylightSavingTime(); // returns **true

in .net 4.5

DateTime dateUsing45 = new DateTime(2011, 4, 7); // ticks 634377312000000000
dateUsing45.ToUniversalTime(); //ticks  **634377276000000000    
bool isDaylightST = dateUsing45.IsDaylightSavingTime(); // returns **false

System.Threading.Thread.CurrentThread.CurrentCulture在两种情况下都是{it-IT}。

实际上,我使用的日期处于(意大利以及所有使用WET的国家)夏令时范围内,因此似乎在框架中存在一个(巨大的)错误。但是我没有找到任何有用的信息。

我在两台机器上进行了验证:

  • 区域设置仍设置为意大利语。
  • “自动调整时钟以进行夏令时更改”已选中。
  • 打开区域设置和设置->在选项卡位置上 ->当前位置仍为意大利。
  • 操作系统为Windows 7 x64。

已解决:

框架更新将DynamicDaylightTimeDisabled的值更改为1。要解决此问题,需要将其转换为0并重新启动。另一种方法是使用时钟UI表单。


使用 NodaTime。.NET 的 DateTime 类存在一些问题。 - Soner Gönül
2
你确定 CurrentCulture 是正确的吗?.NET 4.5机器的区域设置是否被更改了? - Jeppe Stig Nielsen
我也无法重现这个问题。无论是使用我的本地语言(nl-BE)还是意大利语(it-IT)。 - Jensen
当您运行测试时,时区和“自动调整时钟以适应夏令时更改”设置是否相同? - LostInComputer
1
在假定框架存在错误之前,我倾向于非常小心。虽然有一些问题,但大多数问题都来自其他来源。 - Thorsten Dittmar
显示剩余5条评论
2个回答

2

请检查var tziLocal = TimeZoneInfo.Local;的值(参见Shaun的答案),以及它的Id属性。

同样地(我认为),可以打开PowerShell并输入:

Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\TimeZoneInformation -Name TimeZoneKeyName

并检查 TimeZoneKeyName winreg "属性"的值。可以将Get-ItemProperty缩短为gp

根据实验,CurrentCultureCurrentUICultureRegionInfo.CurrentRegion用于确定“本地时间”。

相反,如果您去Windows的控制面板→时钟、语言和区域→日期和时间→日期和时间选项卡→时区部分→更改时区按钮...,更改该时区似乎是有效的。

当然,如果Windows注册表包含错误的意大利设置,通常是ID为"W. Europe Standard Time"(而不是"Romance Standard Time",也不是"Central European Standard Time"),那么在您特定的机器上,这将是一个问题。


在注册表路径HKEY_LOCAL_MACHINE -> SYSTEM -> CURRENTCONTROLSET -> CONTROL -> TIMEZONEINFORMATION中,timezoninfoKey被正确设置为“W. Europe Standard Time”,但我注意到4.5机器上的键“DynamicDaylightTimeDisabled”设置为“1”,而4.0机器上设置为“0”,尽管我已经更改了它,但问题并没有改变。 - Riccardo
我没有这个问题。对我来说,DynamicDaylightTimeDisabled0DaylightStart00 00 03 00 05 00 02 00 00 00 00 00 00 00 00 00(希望意味着“三月的最后一个星期日”)。 - Jeppe Stig Nielsen
你的机器上运行着什么操作系统? - Riccardo
@Riccardo Windows 7 SP1。 - Jeppe Stig Nielsen

2
使用 TimeZoneInfo 类如何?
DateTime dateUsing45 = new DateTime(2011, 4, 7); // ticks 634377312000000000
dateUsing45.ToUniversalTime(); //ticks  **634377276000000000    

TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
var isDaylightST = cstZone.IsDaylightSavingTime(dateUsing45);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接