使用负年份创建 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
,必须做出一些断言:
- 它发生在一天中的什么时间?
- 当时是哪个时区?
- 该日期的时间在该区域内是否有效且明确?
让我们选择午夜时间和 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
。
我正在尝试基于 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
,必须做出一些断言:
- 它发生在一天中的什么时间?
- 当时是哪个时区?
- 该日期的时间在该区域内是否有效且明确?
让我们选择午夜时间和 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
。