DateTime.ToString ("MM / gg / aaaa HH: mm: ss.fff") ha prodotto qualcosa come "14/09/2013 07.20.31.371"


131

Ho un'app WP8, che invierà l'ora corrente a un servizio web.

Ottengo la stringa datetime chiamando

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

Per la maggior parte degli utenti funziona alla grande e mi dà la stringa corretta come "09/10/2013 04:04:31.415". Ma per alcuni utenti la stringa risultante è qualcosa del genere "09/14/2013 07.20.31.371", che causa problemi nel mio servizio web.

È perché qualche problema di formato culturale? Come posso assicurarmi che la stringa del risultato sia delimitata dai due punti anziché dal punto?


2
l'unica differenza sono i due punti contro i punti.
Eldorado,

Fare riferimento ai campioni .Net Standard 2
Sina Lotfi,

Risposte:


244

È perché qualche problema di formato culturale?

Sì. L'utente deve trovarsi in una cultura in cui il separatore temporale è un punto. Sia ":" che "/" sono interpretati in modo sensibile alla cultura in formati personalizzati di data e ora .

Come posso assicurarmi che la stringa del risultato sia delimitata dai due punti anziché dal punto?

Suggerirei di specificare CultureInfo.InvariantCulture:

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

In alternativa, si può semplicemente citare ora e data separatori:

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

... ma questo ti darà risultati "interessanti" che probabilmente non ti aspetti se riesci a far funzionare gli utenti in una cultura in cui il sistema di calendario predefinito non è il calendario gregoriano. Ad esempio, prendi il seguente codice:

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

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

Che produce output (il 18 settembre 2013) di:

11/12/1434 15:04:31.750

Suppongo che il tuo servizio web ne sarebbe sorpreso!

In realtà suggerirei non solo di utilizzare la cultura invariante, ma anche di passare a un formato data ISO-8601:

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

Questo è un formato più accettato a livello globale - è anche ordinabile e rende evidente l'ordine del mese e del giorno. (Considerando che il 06/07/2013 potrebbe essere interpretato come il 7 giugno o il 6 luglio a seconda della cultura del lettore.)


grazie Jon. Ho pensato che la stringa del risultato sarebbe esattamente come la stringa del formato. Proverò il tuo suggerimento.
Eldorado,

3
Solo una piccola considerazione. Quando si carica un oggetto CultureInfo da un codice specifico, suggerisco sempre di impostare il useUserOverrideparametro su false, altrimenti alcune impostazioni dell'utente possono sovrascrivere le impostazioni della cultura. Ad esempio nel tuo caso suggerisco di usare new CultureInfo("ar-SA", false).
Davide Icardi,

@DavideIcardi: Interessante, grazie - anche se in questo caso lo scopo di usare l'Arabia Saudita era specificamente quello di dire perché usare la cultura invariante sia probabilmente giusto. Lo terrò presente per i post futuri.
Jon Skeet,

7
A metà di questa ampia risposta, ho iniziato a chiedermi: sarebbe Jon di nuovo? Sì.
Smorfia di disperazione,

Come gestire lo stesso con Html.TextBoxFor (x => x.Date, "{0: MM / dd / yyyy}")?
VISHMAY

9

:ha un significato speciale: è il separatore del tempo. ( Stringhe di formato di data e ora personalizzate ).

Usa \per sfuggire:

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

Oppure usa CultureInfo.InvariantCulture:

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

Suggerirei di andare con il secondo, perché /ha anche un significato speciale (è il separatore della data. ), Quindi puoi avere problemi anche con quello.


2
Non è solo il separatore di date a essere un problema - vedi la mia risposta per un esempio della cultura che influenza anche i numeri reali ...
Jon Skeet,

1
\ non sfugge!
Shereef Marzouk,

8

Puoi usare InvariantCulture perché il tuo utente deve trovarsi in una cultura che utilizza un punto anziché i due punti:

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

7

Recentemente ho riscontrato questo problema con Windows 10 da un'altra direzione e ho trovato la risposta di @JonSkeet molto utile per risolvere il mio problema.

Ho anche fatto ulteriori ricerche con un modulo di test e ho scoperto che quando la cultura corrente era impostata su "no"o "nb-NO"in fase di esecuzione ( Thread.CurrentThread.CurrentCulture = new CultureInfo("no");), la chiamata ToString ("yyyy-MM-dd HH: mm: ss") ha risposto in modo diverso in Windows 7 e Windows 10. Ha restituito quello che mi aspettavo in Windows 7 e HH.mm.ss in Windows 10!

Penso che sia un po 'spaventoso! Dal momento che credevo che una cultura fosse almeno una cultura in qualsiasi versione di Windows.


Sarei piuttosto curioso di scoprire cosa realmente causa questo.
Lauri Peltonen,

2
È stato riconosciuto e corretto come bug di localizzazione di Windows 10. Quindi un aggiornamento di Windows sul computer client risolverà il problema. Maggiori dettagli sono disponibili in questo post del blog: heikniemi.net/hardcoded/2015/08/…
Håkon Seljåsen

Il blog di Jouni Heikniemi, a cui ho collegato sopra, sembra essere rotto. Gli aggiornamenti di Windows rilevanti in cui i problemi sono stati risolti sono stati elencati qui: 2015-10-09: KB3093266 - Windows 10 KB3088956 - Windows Server 2012 R2 e Windows 8.1 KB3088955 - Windows Server 2012 e Windows 8 KB3088957 - Windows 7 SP1, Windows Server 2008 SP2 , Windows Server 2008 R2 SP1 e Windows Vista SP2 Cercando di collegarsi nuovamente al blog, questa volta tramite archive.org: web.archive.org/web/20161030193739/http://www.heikniemi.net/…
Håkon Seljåsen

4

Puoi usare 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);
// I got this result: "02/23/2015 16:42:38.234"

0

Converti data in stringa

Usa il nome Space

using System.Globalization;

Codice

string date = DateTime.ParseExact(datetext.Text, "dd-MM-yyyy", CultureInfo.InstalledUICulture).ToString("yyyy-MM-dd");

Questo non è come convertire una data in una stringa. L'analisi è il contrario!
Vincent Vancalbergh,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.