web-dev-qa-db-fra.com

Comment créer un .NET DateTime à partir du format ISO 8601

J'ai trouvé comment transformer un DateTime en un format ISO 8601 , mais rien sur la procédure inverse en C #.

J'ai 2010-08-20T15:00:00Z, et je veux le transformer en un objet DateTime.

Je pourrais séparer les parties de la chaîne moi-même, mais cela semble être beaucoup de travail pour quelque chose qui est déjà une norme internationale.

109
Ripter

Cette solution utilise l'énumération DateTimeStyles , et fonctionne également avec Z.

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

Cela imprime parfaitement la solution.

127
Mamta D

Bien que MSDN indique que les formats "s" et "o" reflètent la norme, ils ne semblent pouvoir analyser qu'un sous-ensemble limité de celle-ci. C'est notamment un problème si la chaîne contient une spécification de fuseau horaire. (Ce n'est pas le cas pour les formats de base ISO8601, ou les formats à précision réduite, mais ce n'est pas tout à fait votre cas.) C'est pourquoi j'utilise des chaînes de format personnalisées pour l'analyse de ISO8601. Actuellement, mon extrait préféré est:

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

Si cela ne vous dérange pas d'analyser des chaînes sans TZ (je le fais), vous pouvez ajouter une ligne "s" pour augmenter considérablement le nombre de modifications de format couvertes.

27
Alexey Biryukov
using System.Globalization;

DateTime d;
DateTime.TryParseExact(
    "2010-08-20T15:00:00",
    "s",
    CultureInfo.InvariantCulture,
    DateTimeStyles.AssumeUniversal, out d);
21
abatishchev

En voici une qui fonctionne mieux pour moi ( 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()

produit

true
8/20/2010 8:00:00 AM
16
Reb.Cabin

Il semble important de faire correspondre exactement le format de la chaîne ISO pour que TryParseExact fonctionne. Je suppose que Exact est Exact et cette réponse est évidente pour la plupart mais de toute façon ...

Dans mon cas, la réponse de Reb.Cabin ne fonctionne pas car j'ai une entrée légèrement différente selon ma "valeur" ci-dessous.

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

Il y en a quelques milliers supplémentaires et quelques millisecondes.

Cependant, si j’ajoute des .fff au format indiqué ci-dessous, tout va bien.

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

Dans la fenêtre Immédiat VS2010:

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

vrai

Vous devrez peut-être utiliser DateTimeStyles.AssumeLocal aussi selon la zone à laquelle votre heure correspond ...

5
Rob Von Nesselrode

Cela fonctionne très bien dans 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
Zar Shardan