Как создать .NET DateTime из формата ISO 8601 - PullRequest
106 голосов
/ 24 августа 2010

Я нашел, как преобразовать DateTime в формат ISO 8601 , но ничего о том, как сделать обратное в C #.

У меня есть 2010-08-20T15:00:00Z, и я хочучтобы превратить его в DateTime объект.

Я мог бы разделить части строки самостоятельно, но это похоже на большую работу для чего-то, что уже является международным стандартом.

Ответы [ 7 ]

123 голосов
/ 24 августа 2010

В этом решении используется перечисление DateTimeStyles , и оно также работает с Z.

DateTime d2 = DateTime.Parse("2010-08-20T15:00:00Z", null, System.Globalization.DateTimeStyles.RoundtripKind);

Это печатает решение отлично.

26 голосов
/ 19 июля 2013

Хотя MSDN говорит, что форматы «s» и «o» отражают стандарт, они, похоже, способны анализировать только его ограниченное подмножество. Особенно это проблема, если строка содержит указание часового пояса. (Ни для базовых форматов ISO8601, ни для форматов с пониженной точностью - однако это не совсем ваш случай.) Именно поэтому я использую строки произвольного формата, когда дело доходит до анализа ISO8601. В настоящее время мой предпочтительный фрагмент кода:

static readonly string[] formats = { 
    // Basic formats
    "yyyyMMddTHHmmsszzz",
    "yyyyMMddTHHmmsszz",
    "yyyyMMddTHHmmssZ",
    // Extended formats
    "yyyy-MM-ddTHH:mm:sszzz",
    "yyyy-MM-ddTHH:mm:sszz",
    "yyyy-MM-ddTHH:mm:ssZ",
    // All of the above with reduced accuracy
    "yyyyMMddTHHmmzzz",
    "yyyyMMddTHHmmzz",
    "yyyyMMddTHHmmZ",
    "yyyy-MM-ddTHH:mmzzz",
    "yyyy-MM-ddTHH:mmzz",
    "yyyy-MM-ddTHH:mmZ",
    // Accuracy reduced to hours
    "yyyyMMddTHHzzz",
    "yyyyMMddTHHzz",
    "yyyyMMddTHHZ",
    "yyyy-MM-ddTHHzzz",
    "yyyy-MM-ddTHHzz",
    "yyyy-MM-ddTHHZ"
    };

public static DateTime ParseISO8601String ( string str )
{
    return DateTime.ParseExact ( str, formats, 
        CultureInfo.InvariantCulture, DateTimeStyles.None );
}

Если вы не возражаете против разбора строк без TZ (я так делаю), вы можете добавить строку "s", чтобы значительно увеличить количество изменений в покрытом формате.

21 голосов
/ 24 августа 2010
using System.Globalization;

DateTime d;
DateTime.TryParseExact(
    "2010-08-20T15:00:00",
    "s",
    CultureInfo.InvariantCulture,
    DateTimeStyles.AssumeUniversal, out d);
16 голосов
/ 13 мая 2011

Вот тот, который работает лучше для меня ( LINQPad версия):

DateTime d;
DateTime.TryParseExact(
    "2010-08-20T15:00:00Z",
    @"yyyy-MM-dd\THH:mm:ss\Z",
    CultureInfo.InvariantCulture,
    DateTimeStyles.AssumeUniversal, 
    out d);
d.ToString()

производит

true
8/20/2010 8:00:00 AM
5 голосов
/ 14 августа 2012

Кажется важным точно соответствовать формату строки ISO, чтобы TryParseExact работал.Я предполагаю, что Точное - это Точное, и этот ответ очевиден для большинства, но в любом случае ...

В моем случае, ответ Реба.Кабина не работает, так как у меня немного другой ввод в соответствии с моим "значением" ниже.

Значение: 2012-08-10T14:00:00.000Z

Есть несколько лишних тысяч в миллисекундах и может быть больше.

Однако, если я добавлю .fff к формату каккак показано ниже, все в порядке.

Формат строки: @"yyyy-MM-dd\THH:mm:ss.fff\Z"

В непосредственном окне VS2010:

DateTime.TryParseExact(value,@"yyyy-MM-dd\THH:mm:ss.fff\Z", CultureInfo.InvariantCulture,DateTimeStyles.AssumeUniversal, out d);

true

Возможно, вам придетсяиспользуйте DateTimeStyles.AssumeLocal, в зависимости от того, для какой зоны вы используете время ...

3 голосов
/ 18 декабря 2012

Это нормально работает в LINQPad4:

Console.WriteLine(DateTime.Parse("2010-08-20T15:00:00Z"));
Console.WriteLine(DateTime.Parse("2010-08-20T15:00:00"));
Console.WriteLine(DateTime.Parse("2010-08-20 15:00:00"));
0 голосов
/ 24 августа 2010

DateTime.ParseExact(...) позволяет вам сказать парсеру, что представляет каждый символ.

...