我有 ZonedDateTime 值。我需要获取相应的 UTC 时间并将其格式化为 ISO8601 字符串(不带时区)。 什么是正确的“NodaTime 方式”?
我知道我可以使用 ZonedDateTime.ToDateTimeUtc()
方法来获取 .Net DateTime
类型的 Utc。我应该这样做然后只使用 ToString()
吗?
喜欢
var myresult = resZonedDateTime.ToDateTimeUtc().ToString("s")
我真的应该在那里使用“s”吗?
最佳答案
有几种不同的方法,具体取决于您要查找的内容。
首先,您需要决定是否需要像 2014-10-30T16:46:49
这样的值或类似2014-10-30T16:46:49Z
.两者都是 ISO8601 允许的,但尾随 Z
末尾是专门为UTC时使用的。如果您将字符串发送到别处,接收方将不必猜测该值的基础是什么。
如果你想要
Z
, 然后转换你的ZonedDateTime
到Instant
使用.ToInstant()
方法。Instant instant = zdt.ToInstant();
如果您不想要
Z
,但仍希望该值反射(reflect) UTC,然后调整您的ZonedDateTime
到 UTC,然后将其剥离到LocalDateTime
使用它的.LocalDateTime
属性(property)。LocalDateTime ldt = zdt.WithZone(DateTimeZone.Utc).LocalDateTime;
接下来,您需要决定是要使用基于 BCL 的 API 内联格式化字符串,还是要使用基于模式的 API。 Noda Time 两者都支持,你可以阅读 in the user guide .
基于 BCL 的 API 允许您使用您已经熟悉的方法,例如
.ToString()
和.ToString("some format", someCulture)
例如:string s = instant.ToString();
或
string s = ldt.ToString("s", CultureInfo.InvariantCulture);
基于模式的 API 将解析格式字符串的工作与进行实际格式化的工作分开,分为两个步骤:
var pattern = InstantPattern.ExtendedIsoPattern; var s = pattern.Format(instant);
如果您要格式化许多项目,效率会高得多。我通常在使用 LINQ 时使用它。例如:
var pattern = InstantPattern.GeneralPattern; var strings = instants.Select(pattern.Format);
或
var pattern = LocalDateTimePattern.GeneralIsoPattern; var strings = ldts.Select(pattern.Format);
最后,您需要考虑所需的精度。在模式 API 中,“通用”格式精确到整秒。 “扩展”格式包括最多 7 个小数位的小数秒。您还可以使用 Create...
创建自己的模式各种模式类的静态方法。
如果你只是使用 ToString
, 然后请记住,默认格式可能是也可能不是您要查找的格式。同样,您可以传递格式字符串。对于 Instant
值,"g"
精确到整秒,但您可以使用 "yyyy'-'MM'-'dd'T'HH':'mm':'ss;FFFFFFF'Z'"
的自定义字符串如果你需要精确度。对于 LocalDateTime
值,"s"
精确到整秒,"o"
精确到 7 位小数。
同样,所有这些都在 "Text" chapter of the user guide 中,我鼓励您阅读。
关于c# - 获取并格式化与 NodaTime ZonedDateTime 值对应的 UTC 时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26638510/