我试图将DateTime对象转换为ISO8601字符串,但结果却出错了。我已经查看了stackoverflow,但无法找到正确的解决方案。
我从" 2017-06-26T20:45:00.070Z"的日期时间字符串开始由newtonoft从json反序列化并转换为C#中的DateTime对象,相当于:
var theTime = new DateTime(2017, 6, 26, 20, 45, 00, 70, DateTimeKind.Utc);
现在我需要将时间转换回原来的UTC格式字符串,以便在另一种算法中使用它,但我尝试的每次转换都不会将其返回到原始字符串。不确定我做错了什么。
我试过了:
var newTime = theTime.UtcNow.ToString("o");
// returns "2017-06-26T00:00:00.0000000Z"
var newTime2 = theTime.Date.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.sssZ");
// returns "2017-06-26T00:00:00.00Z"
我在做错了什么?我希望使用toISOString()来执行js将使用的内容,这是我在newTime2日期时间格式中列出的内容,但它也没有显示时间。
谢谢!
答案 0 :(得分:28)
观察:
// Your input
DateTime dt = new DateTime(2017, 6, 26, 20, 45, 0, 70, DateTimeKind.Utc);
// ISO8601 with 7 decimal places
string s1 = dt.ToString("o", CultureInfo.InvariantCulture);
//=> "2017-06-26T20:45:00.0700000Z"
// ISO8601 with 3 decimal places
string s2 = dt.ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", CultureInfo.InvariantCulture);
//=> "2017-06-26T20:45:00.070Z"
一些事情:
请勿在格式字符串中使用Z
。这不是valid format specifier,因此它被视为输出的字符。它将在每个字符串中,无论输入日期时间的.Kind
设置如何。
使用DateTime
,使用K
- 通过将.Kind
附加到Z
的输出或偏移量来正确传达DateTimeKind.Utc
来自DateTimeKind.Local
的UTC,或DateTimeKind.Unspecified
的任何内容。
虽然T
将作为字符输出,因为它不是有效的格式说明符,但我建议始终明确说明这些内容,所以更喜欢'T'
。
使用fff
将始终返回三位小数(毫秒)。如果要在零时省略小数,请改用FFF
。您对sss
的使用无效。
传递CultureInfo.InvariantCulture
是一种很好的做法,因为它可以帮助您避免当前文化可能使用不同日历系统的问题。例如,ar-SA
使用UmAlQuraCalendar
,而不是ISO 8601要求的公历格里高利历。
在您尝试的代码中,您调用了theTime.UtcNow
- 不会编译。 UtcNow
是静态属性,而不是实例属性。
同样在您的代码中,您调用了theTime.Date.ToUniveralTime()
- 也不要这样做。 .Date
会将时间组件设置为零,.ToUniversalTime()
将无效,因为输入值已经为DateTimeKind.Utc
。
答案 1 :(得分:0)
问题是您使用UTC
或UniversalTime
等文化标准会失去准确性。如果您只是打印DateTime
:
var theTime = new DateTime(2017, 6, 26, 20, 45, 00, 70,
DateTimeKind.Utc);
Console.WriteLine(theTime);
6/26/2017 8:45:00 PM
您可以详细了解此问题here。
解决方案是不使用任何“文化”。 (例如,UniversalTime
或UtcNow
)。这些文化标准从不包括毫秒......因为没有文化,人们真正关心所有这些往往是几毫秒。
<强>解决方案:强>
var newTime = theTime.ToString("o");
Console.WriteLine(newTime);
2017-06-26T20:45:00.0700000Z