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

问题描述

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

这可以被认为是一个错误修正,但是仍然是不兼容的更改。在Windows数据库中,将在IANA时区数据库中表示为24:00(“午夜之后”)的转换表示为23:59:59.999。 Noda Time 1.x和2.x中的BclDateTimeZone将使用提供的此值,从而导致(例如)一天的开始时间比预期的时间早一毫秒(但与TimeZoneInfo的行为相匹配)。 Noda Time 3.0将改为识别此模式并将其解释为第二天的午夜,与“正确”的行为相匹配。

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

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

Instant i1 = Instant.FromDateTimeUtc(new DateTime(2020,9,10,22,59,999,DateTimeKind.Utc));
Instant i2 = Instant.FromDateTimeUtc(new DateTime(2020,23,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();

输出(框架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,999,DateTimeKind.Utc));
Instant i2 = Instant.FromDateTimeUtc(new DateTime(2012,03,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,999)的“神奇”初始值-通过修改乔恩·斯凯特(Jon Skeet)的示例(已发布在链接的GitHub问题上):

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

LocalDate date = new LocalDate(2012,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)

谢谢,乔恩!

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...