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