DateTime.TryParse无法解析DateTime.MinValue

我正在使用一个名为Json.NET的库,它在内部使用以下代码将JSON字符串解析为DateTime:

if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt)) { dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling); SetToken(JsonToken.Date, dt); return dt; } 

我认为Json.NET搞砸了转换,但看起来它是DateTime.TryParse本身就是拙劣的价值。

当我解析以下有效的Iso日期(对应于UTC DateTime.MinValue)时:

 string json = "0001-01-01T00:00:00+00:00"; DateTime dt; DateTime.TryParse(json, invariantCulture, DateTimeStyles.RoundtripKind, out dt); 

结果是本地化的DateTime: {0001-01-01 8:00:00 PM} ,当转换回Utc时间时, {0001-01-02 0:00:00 PM} 。 基本上,日期下溢,这正是您期望DateTimeStyles.RoundtripKind要避免的问题。

我该如何避免这种情况?

为什么要使用DateTimeStyles.RoundtripKind? RoundtripKind的文档说:

使用“o”或“r”标准格式说明符将DateTime对象转换为字符串时,将保留日期的DateTimeKind字段,然后将该字符串转换回DateTime对象。

“o”或“r”标准格式说明符的字符串输出与您尝试解析的ISO 8601字符串不同。 对我来说听起来并不像RoundtripKind真的应该使用任何日期时间字符串格式。 当字符串采用特定格式时,听起来像往返是DateTime.Kind属性。

既然你知道你试图解析的字符串的格式,那么我建议使用DateTime.TryParseExact。

我不得不支持几个不同版本的ISO 8601字符串 – 这些格式中的任何一种都是ISO 8601中的有效日期时间值(并且还有更多日期,时间和小数秒的选项,但我不是那些) :

0001-01-01T00:00:00 + 00:00

0001-01-01T00:00:00Z

这是一种可以处理以下任一格式的方法:

 private bool TryParseIso8601(string s, out DateTime result) { if (!string.IsNullOrEmpty(s)) { string format = s.EndsWith("Z") ? "yyyy-MM-ddTHH:mm:ssZ" : "yyyy-MM-ddTHH:mm:sszzz"; return DateTime.TryParseExact(s, format, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out result); } result = new DateTime(0L, DateTimeKind.Utc); return false; }