几个时区(欧洲/尼科西亚)的 DST 进入时间使用 System.Globalization C# 报告错误的日期

Posted

技术标签:

【中文标题】几个时区(欧洲/尼科西亚)的 DST 进入时间使用 System.Globalization C# 报告错误的日期【英文标题】:DST Entry time for few Timezone (Europe/Nicosia) are reporting wrong date using System.Globalization C# 【发布时间】:2020-11-26 10:09:04 【问题描述】:

我正在尝试使用 C# 中的 System.Globalization 类获取 2020 年时区“Antarctica/McMurdo”的 DST 进入时间。我收到他们作为

DST Entry Time: 9/29/2020 2:00:00 AM
DST Exit Time: 4/5/2020 2:59:59 AM

但根据https://www.timeanddate.com/time/change/antarctica/mcmurdo,实际 DST 进入时间应该是 2020 年 9 月 27 日凌晨 2:00:00

收到的条目时间已经在 DST 中,因此我的测试程序失败了,因为时间偏移没有发生。

下面是sn-p使用的代码

var currTimeZone = TimeZone.CurrentTimeZone;

var dstInfo = currTimeZone.GetDaylightChanges(now.Year);

DSTEntry = dstInfo.Start.ToString();

以下是我正在运行的 Mono 和 Ubuntu 的版本

Ubuntu 16.04.3 LTS

Mono JIT 编译器版本 5.4.0.201

这是zdump的输出

$ zdump Antarctica/McMurdo -v 2019,2022

南极洲/麦克默多 2019 年 4 月 6 日星期六 13:59:59 UT = 2019 年 4 月 7 日星期日 02:59:59 NZDT isdst=1 gmtoff=46800

南极洲/麦克默多 2019 年 4 月 6 日星期六 14:00:00 UT = 2019 年 4 月 7 日星期日 02:00:00 NZST isdst=0 gmtoff=43200

南极洲/麦克默多 2019 年 9 月 28 日星期六 13:59:59 UT = 2019 年 9 月 29 日星期日 01:59:59 NZST isdst=0 gmtoff=43200

南极洲/麦克默多 2019 年 9 月 28 日星期六 14:00:00 UT = 2019 年 9 月 29 日星期日 03:00:00 NZDT isdst=1 gmtoff=46800

南极洲/麦克默多 2020 年 4 月 4 日星期六 13:59:59 UT = 2020 年 4 月 5 日星期日 02:59:59 NZDT isdst=1 gmtoff=46800

南极洲/麦克默多 2020 年 4 月 4 日星期六 14:00:00 UT = 2020 年 4 月 5 日星期日 02:00:00 NZST isdst=0 gmtoff=43200

南极洲/麦克默多 2020 年 9 月 26 日星期六 13:59:59 UT = 2020 年 9 月 27 日星期日 01:59:59 NZST isdst=0 gmtoff=43200

南极洲/麦克默多 2020 年 9 月 26 日星期六 14:00:00 UT = 2020 年 9 月 27 日星期日 03:00:00 NZDT isdst=1 gmtoff=46800

南极洲/麦克默多 2021 年 4 月 3 日星期六 13:59:59 UT = 2021 年 4 月 4 日星期日 02:59:59 NZDT isdst=1 gmtoff=46800

南极洲/麦克默多 2021 年 4 月 3 日星期六 14:00:00 UT = 2021 年 4 月 4 日星期日 02:00:00 NZST isdst=0 gmtoff=43200

南极洲/麦克默多 2021 年 9 月 25 日星期六 13:59:59 UT = 2021 年 9 月 26 日星期日 01:59:59 NZST isdst=0 gmtoff=43200

南极洲/麦克默多 2021 年 9 月 25 日星期六 14:00:00 UT = 2021 年 9 月 26 日星期日 03:00:00 NZDT isdst=1 gmtoff=46800

有人可以帮我解决这个时间问题吗?或者这是来自 C# 正在读取的 DLL/timezone_database 的错误?

谢谢

【问题讨论】:

你能告诉我们你在哪个平台上?使用TimeZone.CurrentTimeZone(而不是通过 ID 查找系统时区)很难分辨。如果您使用的是 Windows,则 Windows 时区数据可能是错误的。如果您在 Unix 机器上,下一步将是查看机器上的时区文件。一种选择是改用我的NodaTime 库,这当然是正确的:) 乔恩,我正在使用 Mono 在 Linux 平台上运行这个程序。那么,您能否建议我从 .net 库在 Linux 中读取这些时区信息的位置?我检查了用于南极洲/麦克默多时区的“字符串 /usr/share/zoneinfo/NZ”,我发现了以下条目“NZST-12NZDT,M9.5.0,M4.1.0/3”。根据这个 DST 条目应该是 9 月的第 5 周(周日)。我们的环境中不存在 NodaTime 库支持。所以,不能用。 好吧,如果您使用的是 Mono,它可能与使用 .NET Core 完全不同——这取决于您使用的 Mono 版本。请问你能澄清一下吗? (此外,如果您使用 .NET Core 而不是 Mono,您会看到同样的情况吗?)不确定您所说的“我们的环境中不支持 NodaTime 库。所以,不能使用它。”它只是一个图书馆 - 你的意思是你不能第三方图书馆?鉴于其中有多少将是特定于上下文的,如果您在问题中提供 lot 更多详细信息,这将非常有帮助。 (哪种 Linux 风格,哪个版本?同上单声道) 此外,如果您可以运行 zdump -i Antarctica/McMurdo -c 2019,2022 并将其输出包含在问题中,那将会有所帮助。 请使用所有这些信息编辑问题,而不是仅使用添加 cmets。 (在 cmets 中阅读要困难得多,并且 cmets 都应该被视为瞬态的——这些信息对于回答问题至关重要。) 【参考方案1】:

来自the documentation on the TimeZone类:

警告

此 API 现已过时

...

ⓘ重要

尽可能使用TimeZoneInfo 类而不是TimeZone 类。

...

TimeZone 类仅支持一个夏令时 当地时区的调整规则。结果,TimeZone 类可以准确报告夏令时信息或 仅在 UTC 和本地时间之间转换 最新调整规则生效。相比之下,TimeZoneInfo 类支持多种调整规则,这使得可以 使用历史时区数据。

简而言之,不要使用 TimeZone

【讨论】:

以上是关于几个时区(欧洲/尼科西亚)的 DST 进入时间使用 System.Globalization C# 报告错误的日期的主要内容,如果未能解决你的问题,请参考以下文章

黑莓浏览器 Javascript 时间 DST 问题

DST 结束时的 Laravel Carbon addHour()

Python 3.9:使用标准库构造 DST 有效时间戳

从一个本地时区到另一个本地时区的 Python 日期时间转换(+ 奖励 DST)

如何显示 dst 空闲时区偏移量?

马来西亚与新加坡两国的标准时间为UTC+8