2014-02-07 3 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}, что при преобразовании обратно в У дает {0001-01-02 0:00:00 PM}. По сути, дата не заполнена, и это именно та проблема, которую вы бы ожидали от DateTimeStyles.RoundtripKind.

Как избежать этого сценария?

ответ

3

Зачем использовать DateTimeStyles.RoundtripKind? Документация RoundtripKind говорит:

DateTimeKind поле даты сохраняется, когда объект DateTime преобразуется в строку с помощью «о» или «R» стандартный спецификатор формата, а строка затем преобразуется обратно в объект DateTime.

Строка, выводимая из спецификаторов стандартного формата «o» или «r», не похожа на строку ISO 8601, которую вы пытаетесь проанализировать. Мне не кажется, что RoundtripKind действительно должен работать с любым форматом строки даты. Похоже, что путешествие в оба конца для свойства DateTime.Kind, когда строка находится в определенном формате.

Поскольку вы знаете формат строки, которую вы пытаетесь проанализировать, я бы предложил использовать DateTime.TryParseExact.

Мне пришлось поддерживать пару различных версий строки ISO 8601 - любой из этих форматов является допустимыми значениями даты и времени в ISO 8601 (и есть еще больше опций для дат, времени и дробных секунд, но я didn «т те):

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

Смежные вопросы