我应该如何将本地DateTime转换为Instant?

Sam*_*Sam 10 .net nodatime

我有一种情况,我想将其转换DateTimeInstant.我相信DateTimeKindLocal.

鉴于它DateTime在一个被调用的变量中time,我在库中找到的最接近的是:

Instant.FromDateTimeUtc(time.ToUniversalTime())
Run Code Online (Sandbox Code Playgroud)

这似乎是合理的,但我想确定这是完全可靠的,并且没有数据丢失或损坏的风险.我不确定这是否是进行转换的最佳方式,或者是否有更可靠的方法.

我查看了NodaTime的BCL转换页面,它说了以下关于这种情况:

请注意,没有转换到DateTime某种类型Local- 这实际上是系统默认时区,您通常应该明确开始.

Mat*_*int 18

你错过了一个关键点:A DateTime的类型Local并不总是完全代表一个独特的时刻.这就是为什么没有直接映射到Instant.

在后退DST过渡期间,本地DateTime可以表示两个可能的时刻中的任何一个.如果您要将其转换为a Instant,那么您需要决定应该选择哪个时刻.

在你给出的答案中,我假设你timezone从下列之一获得:

var timezone = DateTimeZoneProviders.Tzdb.GetSystemDefault();
Run Code Online (Sandbox Code Playgroud)

要么

var timezone = DateTimeZoneProviders.Bcl.GetSystemDefault();
Run Code Online (Sandbox Code Playgroud)

这个任务都可以.那你给的代码:

var localTime = LocalDateTime.FromDateTime(time);
var zonedTime = localTime.InZoneStrictly(timeZone);
return zonedTime.ToInstant();
Run Code Online (Sandbox Code Playgroud)

这是完全正确的,但自从您使用后InZoneStrictly,您将AmbiguousTimeException在后退过渡期间得到一个.

您可以通过使用来避免这种情况InZoneLeniently,这将选择后两种可能性(通常是"标准"时间).但更重要的是,您可以使用InZone并提供标准或自定义解析器来更精确地控制行为.

关于你原来的方法:

Instant.FromDateTimeUtc(time.ToUniversalTime())
Run Code Online (Sandbox Code Playgroud)

这没关系,也不会破坏你的数据,但要明白它将依赖于BCL的本地转换行为.它是相同的InZoneLeniently,因为模糊值将被视为"标准"时间.

这是NodaTime如何提供更精确的API的一个很好的例子.您没有做出假设,而是有机会具体并提供自定义行为.最终,您获得了相同的结果,但它将此问题置于前台而不是隐藏它.