c# 将日期时间对象转换为 iso 8601 字符串
c# convert datetime object to iso 8601 string
我正在尝试将 DateTime 对象转换为 ISO8601 字符串,但总是得到错误的结果。我在 Whosebug 上四处寻找,但找不到合适的解决方案。
我从日期时间字符串“2017-06-26T20:45:00.070Z”开始,它由 newtonsoft 从 json 反序列化并转换为 C# 中的 DateTime 对象,相当于:
var theTime = new DateTime(2017, 6, 26, 20, 45, 00, 70, DateTimeKind.Utc);
现在我需要将那个时间转换回它的原始 UTC 格式字符串以在另一个算法中使用它,但我尝试的每个转换都不会 return 将它转换为原始字符串。不知道我做错了什么。
我试过:
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"
我做错了什么?我想要等效于 js 使用 toISOString() 所做的事情,这是我在 newTime2 日期时间格式中列出的内容,但它也没有显示时间。
谢谢!
问题是您使用 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。
解决方案是不使用任何 "culture"。 (例如,UniversalTime
或 UtcNow
)。这些文化标准从不包括毫秒......因为没有一种文化让人们真正关心毫秒。
解法:
var newTime = theTime.ToString("o");
Console.WriteLine(newTime);
2017-06-26T20:45:00.0700000Z
观察:
// 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
- 通过在 DateTimeKind.Utc
的输出中附加 Z
来正确传达 .Kind
,或 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
.
我正在尝试将 DateTime 对象转换为 ISO8601 字符串,但总是得到错误的结果。我在 Whosebug 上四处寻找,但找不到合适的解决方案。
我从日期时间字符串“2017-06-26T20:45:00.070Z”开始,它由 newtonsoft 从 json 反序列化并转换为 C# 中的 DateTime 对象,相当于:
var theTime = new DateTime(2017, 6, 26, 20, 45, 00, 70, DateTimeKind.Utc);
现在我需要将那个时间转换回它的原始 UTC 格式字符串以在另一个算法中使用它,但我尝试的每个转换都不会 return 将它转换为原始字符串。不知道我做错了什么。
我试过:
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"
我做错了什么?我想要等效于 js 使用 toISOString() 所做的事情,这是我在 newTime2 日期时间格式中列出的内容,但它也没有显示时间。
谢谢!
问题是您使用 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。
解决方案是不使用任何 "culture"。 (例如,UniversalTime
或 UtcNow
)。这些文化标准从不包括毫秒......因为没有一种文化让人们真正关心毫秒。
解法:
var newTime = theTime.ToString("o");
Console.WriteLine(newTime);
2017-06-26T20:45:00.0700000Z
观察:
// 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
- 通过在DateTimeKind.Utc
的输出中附加Z
来正确传达.Kind
,或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
.