Jak tworzyć a.NET DateTime z formatu ISO 8601

Znalazłem, jak zmienić DateTime w ISO 8601 format, ale nic na temat tego, jak zrobić odwrotnie w C#.

Mam 2010-08-20T15:00:00Z i chcę przekształcić go w DateTime obiekt.

Mógłbym sam rozdzielić części łańcucha, ale wydaje się, że to dużo pracy dla czegoś, co jest już międzynarodowym standardem.

Author: Liam, 2010-08-24

7 answers

To rozwiązanie wykorzystuje DateTimeStyles Wyliczenie, a także działa z Z.

DateTime d2 = DateTime.Parse("2010-08-20T15:00:00Z", null, System.Globalization.DateTimeStyles.RoundtripKind);
To doskonale drukuje rozwiązanie.
 104
Author: Mamta D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-15 18:14:24
using System.Globalization;

DateTime d;
DateTime.TryParseExact(
    "2010-08-20T15:00:00",
    "s",
    CultureInfo.InvariantCulture,
    DateTimeStyles.AssumeUniversal, out d);
 21
Author: abatishchev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-13 18:11:10

Chociaż MSDN mówi, że formaty" s "I" o " odzwierciedlają standard, wydają się być w stanie przeanalizować tylko ograniczony jego podzbiór. Szczególnie jest to problem, jeśli łańcuch zawiera specyfikację strefy czasowej. (Podobnie jak w przypadku podstawowych formatów ISO8601 , czy formatów o zmniejszonej precyzji-jednak nie jest to dokładnie Twój przypadek.) Dlatego korzystam z niestandardowych ciągów formatowych, jeśli chodzi o parsowanie ISO8601. Obecnie Mój ulubiony fragment to:

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 );
}

If you don ' t mind parsing TZ-less strings (Tak), możesz dodać linię "s", aby znacznie rozszerzyć liczbę objętych zmian formatu.

 20
Author: Alexey Biryukov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-19 17:46:11

Oto jeden, który działa lepiej dla mnie (linqpad version):

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

Produkuje

true
8/20/2010 8:00:00 AM
 15
Author: Reb.Cabin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-15 18:15:18

Wydaje się ważne, aby dokładnie dopasować format łańcucha ISO do działania TryParseExact. Myślę, że Exact jest dokładny i ta odpowiedź jest oczywista dla większości, ale w każdym razie...

W moim przypadku, Reb.Odpowiedź kabiny nie działa, ponieważ mam nieco inny wkład, jak na moją" wartość " poniżej.

Value: 2012-08-10T14:00:00.000Z

Jest tam kilka dodatkowych 000 na milisekundy i może być ich więcej.

Jeśli jednak dodam trochę .fff do formatu, jak pokazano poniżej, wszystko jest w porządku.

Format String: @"yyyy-MM-dd\THH:mm:ss.fff\Z"

W oknie VS2010:

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

True

Możesz również użyć DateTimeStyles.AssumeLocal w zależności od strefy, dla której jest Twój czas...

 3
Author: Rob Von Nesselrode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-18 15:09:24

To działa dobrze w 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"));
 3
Author: Zar Shardan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-17 14:20:23

DateTime.ParseExact(...) pozwala powiedzieć parserowi, co każdy znak reprezentuje.

 -1
Author: Jerod Houghtelling,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-30 09:53:06