野田时间即时到 CET

Noda Time Instant to CET

我在 .net 核心项目中使用 Noda Time 库 (v 2.0.3) 进行日期时间处理。然而;我在将瞬间转换为 CET 日期时间时遇到一些问题。

我对 Noda Time 还很陌生,可能用错了(CET tz-db 条目根本不是指 CET)?

示例代码

// get current system instant
var systemInstant = SystemClock.Instance.GetCurrentInstant();

// get oslo zoneddatetime from instant
var osloDateTime = systemInstant.InZone(DateTimeZoneProviders.Tzdb["Europe/Oslo"]);
// get CET(?) zoneddatetime from instant
var cetDateTime = systemInstant.InZone(DateTimeZoneProviders.Tzdb["CET"]);

// output
Debug.WriteLine(osloDateTime.ToString());
Debug.WriteLine(cetDateTime.ToString());

上面示例代码的输出给我:

2017-06-16T22:28:16 Europe/Oslo (+02)
2017-06-16T22:28:16 CET (+02)

实际上我希望 CET 分区时间是 21:28:16 (UTC+1) 而不是 22:28:16 (UTC+2)。 UTC+1 也是 Time and date website 显示的内容。

如果你看DateTimeZoneProviders.Tzdb["CET"]的结果,它的最小偏移量+1,最大偏移量+2,所以我认为它指的是实际中欧时区(包括中欧夏令时 [CEST])。

由于您选择的日期为夏令时,因此为UTC+2

如果您尝试以下操作,您将获得 CET 的 UTC+1:

Instant.FromDateTimeUtc(new DateTime(2017, 01, 01, 12, 0, 0, DateTimeKind.Utc)).InZone(DateTimeZoneProviders.Tzdb["CET"]

IANA 时区数据库中 europe 文件的 Zone 行包含 CET 时区 ID 的这一行:

Zone    CET     1:00    C-Eur   CE%sT

那么C-Eur规则的结束循环就是这一对行:

Rule    C-Eur   1981    max -   Mar lastSun  2:00s  1:00    S
Rule    C-Eur   1996    max -   Oct lastSun  2:00s  0   -

因此每年三月的最后一个星期日凌晨 2 点进入 UTC+2,并在每年 10 月的最后一个星期日凌晨 2 点返回 UTC+1。

请注意,CET 时区的 "abbreviation" 会在 "CET" 和 "CEST" 之间变化 - 这可能会误导您。但是根据 IANA 数据库,Noda Time 遵循 ID "CET" 的定义。

这只是避免使用缩写的另一个原因,而是使用完整的区域 ID,例如明确的 Europe/Oslo。我建议避免尝试完全使用 "a CET date-time" 的概念。