2014-02-07 19 views
6

我使用了一個名爲Json.NET庫,它使用下面的代碼內部的JSON字符串解析成一個DateTime:DateTime.TryParse無法解析DateTime.MinValue

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要避免的問題。

如何避免這種情況?

回答

3

爲什麼使用DateTimeStyles.RoundtripKind?對於RoundtripKind文檔說:

當DateTime對象被轉換爲使用「○」或「r」標準格式說明字符串的日期的DateTimeKind字段被保留,然後將字符串被轉換回一個DateTime對象。

從「o」或「r」標準格式說明符輸出的字符串不像您試圖解析的ISO 8601字符串。對我來說聽起來並不像RoundtripKind實際上應該可以使用任何日期時間字符串格式。這聽起來像是當字符串處於特定格式時往返的DateTime.Kind屬性。

由於您知道您嘗試解析的字符串格式,因此我建議使用DateTime.TryParseExact。

我不得不支持幾個不同版本的ISO 8601字符串 - 這些格式中的任何一種都是ISO 8601中的有效日期時間值(並且日期,時間和小數秒還有更多選項,但我沒有「T那些):

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; 
} 
+0

我包含的代碼來自一個名爲'Json.NET'的流行庫。如果他們使用'DateTimeStyles.RoundtripKind'確實不正確,那麼我會說這是他們的錯誤。 – Alain