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.
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.
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.
using System.Globalization;
DateTime d;
DateTime.TryParseExact(
"2010-08-20T15:00:00",
"s",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal, out d);
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
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 ...
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"));