使用负年份创建 Instant

Create Instant using a negative year

我正在尝试基于 B.C.E 创建一个 Instant。公历年份。

这是我目前的情况:

Instant.FromDateTimeOffset(new DateTimeOffset(-1000, 10, 01,
                                              0, 0, 0, 0,
                                              new System.Globalization.GregorianCalendar(),
                                              new TimeSpan()));

我收到错误:

An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll Additional information: Year, Month, and Day parameters describe an un-representable DateTime.

编辑

NodaTime 做了一些研究,我发现它确实有能力表示我想要的日期,因为它可以接受来自 Unix 纪元的负数:

The Noda Time Instant type represents a point on this global timeline: the number of ticks which have elapsed since the Unix epoch. The value can be negative for dates and times before 1970 of course - the range of supported dates is from around 27000 BCE to around 31000 CE in the Gregorian calendar. - http://nodatime.org/1.3.x/userguide/concepts.html

所以我想知道如何使用 NodaTime 来做到这一点,而不是创建我自己的实现,例如 here 提到的那样。

在野田时间创建BCE日期的正确方法是这样的:

LocalDate date = new LocalDate(Era.BeforeCommon, 1000, 10, 1);

这给出了一个LocalDate对象,它代表刚好有一个日期。您要求 Instant,它代表一个确切的时间点。这是两个截然不同的概念。

为了从 LocalDate 得到 Instant,必须做出一些断言:

  1. 它发生在一天中的什么时间?
  2. 当时是哪个时区?
  3. 该日期的时间在该区域内是否有效且明确?

让我们选择午夜时间和 UTC 时区:

Instant instant = date.AtMidnight().InUtc().ToInstant();

由于我们选择了 UTC,因此我们不必解决 valid/unambiguous 问题。对于其他区域,我们将使用 InZone 方法之一,而不是 InUtc.

此外 - 您确实可以直接创建 Instant(如 Caramiriel 所示),但要小心。第 1 年 BCE 由第 0 年表示,因此如果您想要 1000 BCE,则必须通过 -999,而不是 -1000。

Instant instant = Instant.FromUtc(-999, 10, 1, 0, 0, 0);

同样,这假定时间为午夜和 UTC 时区。

最后,请记住 none 这些日历系统或时区在那个时期确实存在,并且通常在处理如此古老的日期时,时间部分不是很准确或相关。因此,我建议您尝试只使用 LocalDate 对象,如果可以的话根本不要使用 Instant