.net - Windows 上的 'GTB Standard Time' 夏令时转换开始时间测试失败

标签 .net datetime testing timezone dst

我编写了几个将时间从特定时区转换为 UTC 的测试。

规则规定,在欧洲,时钟在 01:00 UTC 向前移动,对于“GTB 标准时间”,这意味着 +2 UTC,例如03:00:00 。

但是,我发现使用 TimeZoneInfo.IsDaylightSavingTime(dateTime) 方法在不同平台(Linux 与 Windows)的测试中存在差异。

我为 DST 转换日期和时间创建了一个新的测试对象:

var testDate = new DateTime(2019, 03, 31, 03, 20, 00); //20 minutes after Daylight Saving Time start
...

并将其传递给 TimeZoneInfo“timeZone”对象,其中时区设置为“GTB 标准时间”:

...
    var timeZone = TimeZoneInfo.FindSystemTimeZoneById("GTB Standard Time");
    return timeZone.IsDaylightSavingTime(testDate);
}

这将返回 False,尽管 2019-03-31 本地 03:20:00 夏令时应该已经开启。这应该返回 True。

我设法仅在 Windows 上使用 .Net 时区的内置数据库重复此测试。使用 tzdata db(例如 NodaTime)为此测试返回 True

令人困惑的部分是 我手动给 timeZone 对象抛了一个错误,看看 TimeZoneInfo 对象有什么额外的信息,发现 DST 开始实际上是正确的:

timeZone.GetAdjustmentRules().First().DaylightTransitionStart.TimeOfDay

返回 03:00:00

有人可以确认这一点吗?还有没有办法检查 Windows 在何处采用 DST 时间?我可以在不使用任何外部库的情况下使当前测试在 Windows 和 Linux 上都通过吗?

最佳答案

该时区的本地时间在该特定日期从 02:59:59 到 04:00:00,因此 3:20:00 无效。它落入了向前过渡所造成的差距。

根据 the docs for TimeZoneInfo.IsDaylightSavingTime(DateTime) (强调我的)

If the dateTime parameter specifies an invalid time, the method call throws an ArgumentException if the value of the dateTime parameter's Kind property is DateTimeKind.Local; otherwise, the method returns false.

如果可以,请改用 DateTimeOffset 类型,或将 DateTimeDateTimeKind.Utc 一起使用。无论使用哪种方式,都不可能出现无效或模棱两可的本地时间。

如果你不能那样做,那么在 TimeZoneInfo 对象上使用 IsInvalidTimeIsAmbiguousTime 测试你的输入值,然后你可以代码中关于如何处理结果的决定。例如,您可能希望将该实例的 3:20 移动到 4:20。

在时间不明确的情况下,请注意 TimeZoneInfo 上的所有方法(IsDaylightSavingTimeGetUtcOffset 等)都将假定 < em>标准时间 默认情况下,顺序排在第二位。在这些场景中,人们几乎总是想要夏令时。您可以通过调用 GetAmbiguousTimeOffsets 获取两个可用的偏移量并选择较大的一个。

此外,您还提到了 Noda Time - 一个更好的 API,恕我直言。在那里,此类事情由“解析器”处理 如果您调用 LocalDateTime.InZoneLeniently,将使用默认的“宽松”解析器。还有其他解析器,您可以指定自己的解析器。请参阅以 here 开头的文档.

关于.net - Windows 上的 'GTB Standard Time' 夏令时转换开始时间测试失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53153622/

相关文章:

c# - 如何在浏览器中打开链接?

testing - 如何在 Heroku 部署期间更改默认设置 '-DskipTests=true'?

c# - 如何序列化通用对象

c# - 用逗号代替小数将数字格式化为字符串

c# - ConfigurationManager - 如何在 .NET 3.5 中使用连接字符串?

datetime - 如何避免 TYPO3 中的日期时间问题?

python - 如何在 Pandas 中将字节对象类型转换为日期时间

java - 如何将两个 java.sql.Date s 存储到数据库表中,当它们被截断时?

python - 重新读取打开的文件 Python

multithreading - jmeter中单独执行线程组