我有一种情况,我想转换 DateTime
到 Instant
.相信DateTime
的 Kind
将是 Local
.
鉴于DateTime
位于名为 time
的变量中,我能在图书馆找到的最接近的是:
Instant.FromDateTimeUtc(time.ToUniversalTime())
这似乎是合理的,但我想确定这是完全可靠的,并且没有数据丢失或损坏的风险。我不确定这是否是进行转换的最佳方法,或者是否有更可靠的方法。
我看了看NodaTime的BCL Conversions页面,它对这个场景做了以下说明:
Note that there are no conversions to a
DateTime
with a kind ofLocal
- this would effectively be for the system default time zone, which you should generally be explicit about to start with.
最佳答案
你错过了一个关键点:A DateTime
种类是Local
并不总是完全代表一个独特的时刻。这就是为什么没有直接映射到 Instant
.
在回退 DST 转换期间,本地 DateTime
可以代表两个可能的时刻中的任何一个。如果您要将其转换为 Instant
,然后在某个地方您需要决定应该选择哪个时刻。
在您给出的答案中,我假设您获得了 timezone
来自以下之一:
var timezone = DateTimeZoneProviders.Tzdb.GetSystemDefault();
或
var timezone = DateTimeZoneProviders.Bcl.GetSystemDefault();
两者都可以完成这项任务。然后你给的代码:
var localTime = LocalDateTime.FromDateTime(time);
var zonedTime = localTime.InZoneStrictly(timeZone);
return zonedTime.ToInstant();
这是完全正确的,但是由于您使用了
InZoneStrictly
, 你会得到一个 AmbiguousTimeException
在回退过渡期间。您可以通过使用
InZoneLeniently
来避免这种情况。 ,这将选择两种可能性中的后者(通常是“标准”时间)。但更重要的是,您可以改为使用 InZone
并提供标准或定制 resolver更精确地控制行为。关于您的原始方法:
Instant.FromDateTimeUtc(time.ToUniversalTime())
这没问题,不会破坏您的数据,但要了解它会依赖于 BCL 的本地到通用转换行为。与
InZoneLeniently
相同,因为不明确的值将被视为“标准”时间。这是 NodaTime 如何提供更精确的 API 的一个很好的例子。您有机会具体说明并提供自定义行为,而不是做出假设。最后你取得了同样的结果,但它把这个问题带到了前台而不是隐藏它。
关于.net - 我应该如何将本地 DateTime 转换为 Instant?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19417845/