144 votes

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff") a donné quelque chose comme "09/14/2013 07.20.31.371"

J'ai une application WP8, qui enverra l'heure actuelle à un service web.

Je récupère la chaîne de date et heure en appelant

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff")

Pour la plupart des utilisateurs, cela fonctionne très bien et me donne la chaîne correcte comme "09/10/2013 04:04:31.415". Mais pour certains utilisateurs, la chaîne résultante est quelque chose comme "09/14/2013 07.20.31.371", ce qui pose problème dans mon service web.

Est-ce à cause d'un problème de format de culture ? Comment puis-je m'assurer que la chaîne résultante est délimitée par des deux-points au lieu de des points ?

261voto

Jon Skeet Points 692016

Est-ce dû à un problème de format spécifique à une culture?

Oui. Votre utilisateur doit se trouver dans une culture où le séparateur d'heure est un point. Les symboles ":" et "/" sont interprétés de manière spécifique à une culture dans les formats de date et heure personnalisés.

Comment puis-je m'assurer que la chaîne de résultat est délimitée par deux points au lieu d'un point?

Je vous suggère de spécifier CultureInfo.InvariantCulture :

string text = dateTime.ToString("MM/dd/yyyy HH:mm:ss.fff",
                                CultureInfo.InvariantCulture);

Alternativement, vous pouvez simplement mettre entre guillemets les séparateurs d'heure et de date:

string text = dateTime.ToString("MM'/'dd'/'yyyy HH':'mm':'ss.fff");

... mais cela vous donnera des résultats "intéressants" que vous ne vous attendez probablement pas si vos utilisateurs sont dans une culture où le système de calendrier par défaut n'est pas le calendrier grégorien. Par exemple, prenons le code suivant :

using System;
using System.Globalization;
using System.Threading;

class Test
{
    static void Main()        
    {
        DateTime now = DateTime.Now;
        CultureInfo culture = new CultureInfo("ar-SA"); // Arabie Saoudite
        Thread.CurrentThread.CurrentCulture = culture;
        Console.WriteLine(now.ToString("yyyy-MM-ddTHH:mm:ss.fff"));
    }
} 

Cela produit une sortie (le 18 septembre 2013) de :

11/12/1434 15:04:31.750

Je suppose que votre service web serait surpris par cela!

Je suggère en fait non seulement d'utiliser la culture invariante, mais aussi de passer à un format de date ISO-8601 :

string text = dateTime.ToString("yyyy-MM-ddTHH:mm:ss.fff", CultureInfo.InvariantCulture);

C'est un format plus largement accepté - il est également triable et rend l'ordre du mois et du jour évident. (Alors que 06/07/2013 pourrait être interprété comme le 7 juin ou le 6 juillet en fonction de la culture du lecteur.)

13voto

MarcinJuraszek Points 66084

: a une signification spéciale : c'est Le séparateur de temps. (Chaînes de format personnalisées pour les dates et les heures).

Utilisez \ pour l'écaper :

DateTime.ToString(@"MM/dd/yyyy HH\:mm\:ss.fff")

Ou utilisez CultureInfo.InvariantCulture :

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture)

Je vous suggère d'opter pour la deuxième option, car / a également une signification spéciale (c'est Le séparateur de date.), vous pourriez donc rencontrer des problèmes avec cela aussi.

9voto

Jon La Marr Points 588

Vous pouvez utiliser InvariantCulture car votre utilisateur doit être dans une culture qui utilise un point au lieu de deux points :

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture);

8voto

Håkon Seljåsen Points 501

J'ai rencontré ce problème récemment avec Windows 10 depuis une autre direction, et j'ai trouvé la réponse de @JonSkeet très utile pour résoudre mon problème.

J'ai également fait des recherches supplémentaires avec un formulaire de test et j'ai découvert que lorsque la culture actuelle était définie sur "no" ou "nb-NO" à l'exécution (Thread.CurrentThread.CurrentCulture = new CultureInfo("no");), l'appel à ToString("yyyy-MM-dd HH:mm:ss") répondait de manière différente sous Windows 7 et Windows 10. Cela renvoyait ce à quoi je m'attendais sous Windows 7 et HH.mm.ss sous Windows 10!

Je trouve cela un peu effrayant! Puisque je croyais qu'une culture était une culture dans n'importe quelle version de Windows au moins.

5voto

Cosmin Points 860

Vous pouvez utiliser String.Format :

DateTime d = DateTime.Now;
string str = String.Format("{0:00}/{1:00}/{2:0000} {3:00}:{4:00}:{5:00}.{6:000}", d.Month, d.Day, d.Year, d.Hour, d.Minute, d.Second, d.Millisecond);
// J'ai obtenu ce résultat : "02/23/2015 16:42:38.234"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X