【问题标题】:DateTime.TryParse cannot parse DateTime.MinValueDateTime.TryParse 无法解析 DateTime.MinValue
【发布时间】:2014-02-07 20:53:45
【问题描述】:

我正在使用一个名为 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 避免的问题。

如何避免这种情况?

【问题讨论】:

    标签: c# json datetime .net-4.0 json.net


    【解决方案1】:

    为什么要使用 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;
    }
    

    【讨论】:

    • 我包含的代码来自一个名为Json.NET 的流行库。如果他们对DateTimeStyles.RoundtripKind 的使用确实不正确,那么我会说这是他们的一个错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多