c#将datetime对象转换为iso 8601 string

时间:2017-06-27 19:25:26

标签: c# datetime iso8601

我试图将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日期时间格式中列出的内容,但它也没有显示时间。

谢谢!

2 个答案:

答案 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)

问题是您使用UTCUniversalTime等文化标准会失去准确性。如果您只是打印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

解决方案是不使用任何“文化”。 (例如,UniversalTimeUtcNow)。这些文化标准从不包括毫秒......因为没有文化,人们真正关心所有这些往往是几毫秒。

<强>解决方案:

var newTime = theTime.ToString("o");
Console.WriteLine(newTime);
  

2017-06-26T20:45:00.0700000Z