使用负数年份创建Instant [英] Create Instant using a negative year
问题描述
我正在尝试根据B.C.E创建一个 Instant
.公历中的年份.
I am trying to create an Instant
based upon a B.C.E. year in the Gregorian calendar.
这是我到目前为止所拥有的:
Here is what I have so far:
Instant.FromDateTimeOffset(new DateTimeOffset(-1000, 10, 01,
0, 0, 0, 0,
new System.Globalization.GregorianCalendar(),
new TimeSpan()));
我得到了错误:
mscorlib.dll中发生了类型为'System.ArgumentOutOfRangeException'的未处理异常附加信息:Year,Month和Day参数描述了无法表示的DateTime.
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时代的负滴答声:
Doing some research on NodaTime
, I can see that it does have the ability to represent the dates I want, as it can accept negative ticks from the Unix epoch:
Noda Time Instant类型表示此全局时间轴上的一点:自Unix时代以来经过的滴答声数量.当然,对于1970年之前的日期和时间,该值可以为负-在公历中,支持的日期范围是从大约27000 BCE到大约31000 CE.- http://nodatime.org/1.3.x/userguide/concepts.html
所以我想知道如何使用 NodaTime
而不是创建自己的实现,如
So I would like to know how to do this using NodaTime
rather than create my own implementation, as is mentioned here for instance.
推荐答案
在Noda Time中创建BCE日期的正确方法如下:
The correct way to create a BCE date in Noda Time is like this:
LocalDate date = new LocalDate(Era.BeforeCommon, 1000, 10, 1);
这提供了一个 LocalDate
对象,该对象表示仅具有日期.您要求提供一个 Instant
(即时),它表示一个确切的时间点.这是两个截然不同的概念.
This gives a LocalDate
object, which is representative of just having a date. You asked for an Instant
, which represents an exact point in time. These are two very different concepts.
为了从 LocalDate
获取 Instant
,必须做出一些断言:
In order to get an Instant
from a LocalDate
, one has to make a few assertions:
- 一天中的什么时候发生?
- 它在哪个时区?
- 该日期在该区域内的时间是否有效且无歧义?
让我们选择午夜时间和UTC作为时区:
Let's pick midnight for the time and UTC for the time zone:
Instant instant = date.AtMidnight().InUtc().ToInstant();
自从我们选择UTC以来,我们不必解决有效/明确的问题.对于其他区域,我们将使用 InZone
方法之一,而不是 InUtc
.
Since we chose UTC, we didn't have to address the valid/unambiguous question. With other zones, we would use one of the InZone
methods instead of InUtc
.
也-您确实可以直接创建一个 Instant
(如Caramiriel所示),但是要小心.公元前1年用0年表示,因此,如果您想公元前1000年,则必须通过-999,而不是-1000.
Also - you can indeed create an Instant
directly (as Caramiriel showed), but be careful. Year 1 BCE is represented by year 0, so if you want 1000 BCE, you'd have to pass -999, not -1000.
Instant instant = Instant.FromUtc(-999, 10, 1, 0, 0, 0);
同样,这是假设时间为午夜和UTC时区.
Again, this assumes the time at midnight and the UTC time zone.
最后,请记住,在该时间段内实际上不存在这些日历系统或时区,并且通常在处理这么老的日期时,时间部分不是很准确或不相关.因此,我建议您尝试仅根据 LocalDate
对象工作,如果可以的话,根本不要使用 Instant
.
Finally, keep in mind that none of these calendar systems or time zones actually existed during that time period, and usually when working with dates so old, the time part is not very accurate or relevant. Therefore, I recommend you attempt to only work in terms of LocalDate
objects, and not use Instant
at all, if you can.
这篇关于使用负数年份创建Instant的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!