C # DateTime.ToString avec zzz interrompt dans le framework dotnet mais pas dans dotnet core
J'ai mon heure locale au GMT +01: 00 comme heure d'écriture. Je ressens quelque chose, pour moi inattendu, en faisant un ToString de la manière suivante. Et c'est parti:
Démonstration des paramètres du système local avec le fuseau horaire +01: 00 (tous ceux-ci sont en vert):
var myLocalDate = new DateTime(2020, 11, 25, 08, 00, 00, DateTimeKind.Local);
Assert.AreEqual("2020-11-25T08:00:00+01:00", myLocalDate.ToString(@"yyyy-MM-dd\THH:mm:sszzz"));
Assert.AreEqual(DateTimeKind.Local, myLocalDate.Kind);
Assert.AreEqual(myLocalDate, myLocalDate.ToLocalTime());
Et maintenant je crée le même temps, en utc, en soustrayant manuellement une heure et en spécifiant le "utc" comme kind. Mais lorsque j'appelle ToString, le fuseau horaire s'écrit +01: 00, ce que je m'attendrais à être +00: 00:
var myUtcDate = new DateTime(2020, 11, 25, 07, 00, 00, DateTimeKind.Utc);
// THIS Breaks:
Assert.AreEqual("2020-11-25T07:00:00+00:00", myUtcDate.ToString(@"yyyy-MM-dd\THH:mm:sszzz"));
Message d'erreur:
Message: Échec de Assert.AreEqual. Attendu: <2020-11-25T07: 00: 00 + 00: 00>. Réel: <2020-11-25T07: 00: 00 + 01: 00>.
Est-ce que je manque quelque chose sur les dates et les formats ici, ou est-ce peut-être un bogue connu?
Je lance .Net Framework 4.8
Ce message est sur le même problème, je vois: Comment résoudre l'erreur DateTimeInvalidLocalFormat: "Un DateTime UTC est converti en texte dans un format qui n'est correct que pour les heures locales."?
MISE À JOUR:
L'exécution du programme suivant donne des résultats différents dans dotnet framework et dotnet core (comme mentionné par evk):
Console.WriteLine(new DateTime(2025, 11, 25, 07, 00, 00, DateTimeKind.Utc).ToString(@"yyyy-MM-dd\THH:mm:sszzz"));
impressions de base dotnet:
2020-11-25T07: 00: 00 + 00: 00
Impressions du cadre dotnet:
2020-11-25T07: 00: 00 + 01: 00
En outre, lors de l'exécution du framework dotnet en mode débogage, le message suivant de l'assistant de débogage s'affiche, mais est ignoré en interne dans DateTime.ToString ():
Managed Debugging Assistant 'DateTimeInvalidLocalFormat': 'Un DateTime UTC est converti en texte dans un format qui n'est correct que pour les heures locales. Cela peut se produire lors de l'appel de DateTime.ToString à l'aide du spécificateur de format «z», qui inclura un décalage de fuseau horaire local dans la sortie. Dans ce cas, utilisez le spécificateur de format «Z», qui désigne une heure UTC, ou utilisez la chaîne de format «o», qui est la méthode recommandée pour conserver un DateTime dans le texte. Cela peut également se produire lors du passage d'un DateTime à sérialiser par XmlConvert ou DataSet. Si vous utilisez XmlConvert.ToString, passez XmlDateTimeSerializationMode.RoundtripKind pour sérialiser correctement. Si vous utilisez DataSet, définissez DateTimeMode sur l'objet DataColumn sur DataSetDateTime.Utc. '
Réponses
Non, il se comporte comme documenté. De la documentation du zzzspécificateur de format (c'est moi qui souligne):
Avec les
DateTime
valeurs, le spécificateur de format personnalisé "zzz" représente le décalage signé du fuseau horaire du système d'exploitation local par rapport à UTC, mesuré en heures et minutes. Il ne reflète pas la valeur de laDateTime.Kind
propriété d'une instance . Pour cette raison, le spécificateur de format "zzz" n'est pas recommandé pour une utilisation avec desDateTime
valeurs.
C'est peut-être malheureux, mais ce n'est pas un bug.
Notez que .NET Core (et .NET 5.0) ne se comporte apparemment pas comme documenté. Bien que vous puissiez affirmer que c'est "corrigé" dans .NET Core, je suggérerais que se comporter de manière non documentée est un bogue en soi, et qui pourrait rendre la migration de code plus difficile que prévu.
Je vous suggère de suivre la recommandation de la documentation et d'éviter d'utiliser zzz
avec des DateTime
valeurs. Je suggérerais également d' utiliser ma bibliothèque Noda Time à la place, où il n'y a pas d'ambiguïté en termes de valeur "peut-être être local, ou peut-être être UTC", mais c'est une question légèrement différente. (Je ne m'attendrais pas à ce que vous rencontriez ce problème en utilisant Noda Time, et votre autre code date / heure serait, espérons-le, plus clair.)