NodaTime 2.x 与 3.x 中的午夜过渡

Midnight Transitions in NodaTime 2.x vs 3.x

我正在尝试重现 NodaTime 2.x 与 3.x 的不同行为。如所述 here:

This could be considered a bugfix, but it is an incompatible change nonetheless. Transitions that would be represented as 24:00 in the IANA time zone database ("following day midnight") are instead represented as 23:59:59.999 in the Windows database. BclDateTimeZone in Noda Time 1.x and 2.x will use this value as provided, resulting in (for example) the start of a day being reported as one millisecond earlier than intended (but matching the behaviour of TimeZoneInfo). Noda Time 3.0 will instead recognise this pattern and interpret it as midnight of the following day, matching the 'correct' behaviour.

这是我到目前为止尝试过的方法:

TimeZoneInfo tzi = TimeZoneInfo.Utc;
BclDateTimeZone bclDt = BclDateTimeZone.FromTimeZoneInfo(tzi);

Instant i1 = Instant.FromDateTimeUtc(new DateTime(2020, 9, 10, 22, 59, 59, 999, DateTimeKind.Utc));
Instant i2 = Instant.FromDateTimeUtc(new DateTime(2020, 9, 10, 23, 00, 00, 000, DateTimeKind.Utc));
ZonedDateTime zdt1 = new ZonedDateTime(i1, bclDt);
ZonedDateTime zdt2 = new ZonedDateTime(i2, bclDt);

Console.WriteLine(zdt1.PlusHours(1));
Console.WriteLine(zdt2.PlusHours(1));
Console.ReadKey();

输出(Framework 4.8,NodaTime 3.x),与2.x相同:

2020-09-10T23:59:59 UTC (+00)
2020-09-11T00:00:00 UTC (+00)

根据我对 NodaTime 3.x 的理解,两个日期都应输出 9 月 11 日。相比之下,在 NodaTime 2.x 中,第一个日期应该与输出中的一样(9 月 10 日)。但这里有些不对劲。我错过了什么?

Jon Skeet 的评论和链接的 GitHub 问题解释了为什么它不起作用以及如何重现它。但这里有一个工作示例以防万一:

DateTimeZone bclDt = DateTimeZoneProviders.Bcl["E. South America Standard Time"];

// this equals to "AtStartOfDay" of LocalDate at the same DateTimeZone
Instant i1 = Instant.FromDateTimeUtc(new DateTime(2012, 10, 21, 02, 59, 59, 999,  DateTimeKind.Utc));
Instant i2 = Instant.FromDateTimeUtc(new DateTime(2012, 10, 21, 03, 59, 59, 999, DateTimeKind.Utc));
ZonedDateTime zdt1 = new ZonedDateTime(i1, bclDt);
ZonedDateTime zdt2 = new ZonedDateTime(i2, bclDt);

Console.WriteLine(zdt1.PlusHours(-1));
Console.WriteLine(zdt2.PlusHours(-1));

Console.ReadKey();

NodaTime 的输出 2.x:

2012-10-20T22:59:59 E. South America Standard Time (-03)
2012-10-21T00:59:59 E. South America Standard Time (-02)

NodaTime 的输出 3.x:

2012-10-20T22:59:59 E. South America Standard Time (-03)
2012-10-20T23:59:59 E. South America Standard Time (-03)

万一有人在游荡,我如何获得 DateTime(2012, 10, 21, 02, 59, 59, 999) 的“神奇”初始值 - 通过修改 Jon Skeet 的示例,发布在链接的 GitHub 问题上:

DateTimeZone bclDt = DateTimeZoneProviders.Bcl["E. South America Standard Time"];

LocalDate date = new LocalDate(2012, 10, 21);
ZonedDateTime zoned = bclDt.AtStartOfDay(date);
Instant inst = zoned.ToInstant();
ZonedDateTime utc = inst.InUtc();
Console.WriteLine(ZonedDateTimePattern.ExtendedFormatOnlyIso.Format(utc));
Console.ReadKey();

NodeTime 的输出2.x:

2012-10-21T02:59:59.999 UTC (+00)

谢谢,乔恩!