几个时区(欧洲/尼科西亚)的 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# 报告错误的日期的主要内容,如果未能解决你的问题,请参考以下文章
DST 结束时的 Laravel Carbon addHour()