DateTime.ToString ("MM / TT / JJJJ HH: MM: SSFF") führte zu etwas wie "14.09.2013 07.20.31.371".


131

Ich habe eine WP8-App, die die aktuelle Uhrzeit an einen Webdienst sendet.

Ich erhalte die datetime-Zeichenfolge durch Aufrufen

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

Für die meisten Benutzer funktioniert es großartig und gibt mir die richtige Zeichenfolge wie "09/10/2013 04:04:31.415". Für einige Benutzer ist die resultierende Zeichenfolge jedoch so etwas wie "09/14/2013 07.20.31.371"ein Problem in meinem Webdienst.

Liegt es an einem Problem mit dem Kulturformat? Wie kann ich sicherstellen, dass die Ergebniszeichenfolge durch einen Doppelpunkt anstelle eines Punkts getrennt ist?


2
Der einzige Unterschied ist Doppelpunkt gegen Punkt.
Eldorado

Antworten:


244

Liegt es an einem Problem mit dem Kulturformat?

Ja. Ihr Benutzer muss sich in einer Kultur befinden, in der das Zeittrennzeichen ein Punkt ist. Sowohl ":" als auch "/" werden kulturspezifisch in benutzerdefinierten Datums- und Zeitformaten interpretiert .

Wie kann ich sicherstellen, dass die Ergebniszeichenfolge durch einen Doppelpunkt anstelle eines Punkts getrennt ist?

Ich würde vorschlagen, Folgendes anzugeben CultureInfo.InvariantCulture:

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

Alternativ können Sie auch die Zeit- und Datumstrennzeichen angeben:

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

... aber das gibt Ihnen "interessante" Ergebnisse, die Sie wahrscheinlich nicht erwarten, wenn Sie Benutzer in einer Kultur zum Laufen bringen, in der das Standardkalendersystem nicht der Gregorianische Kalender ist. Nehmen Sie zum Beispiel den folgenden Code:

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

Das ergibt eine Ausgabe (am 18. September 2013) von:

11/12/1434 15:04:31.750

Ich vermute, dass Ihr Webdienst davon überrascht wäre!

Ich würde eigentlich vorschlagen, nicht nur die invariante Kultur zu verwenden, sondern auch auf ein ISO-8601-Datumsformat umzusteigen:

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

Dies ist ein global akzeptiertes Format - es ist auch sortierbar und macht die Reihenfolge von Monat und Tag offensichtlich. (Der 06.07.2013 könnte je nach Leserkultur als 7. Juni oder 6. Juli interpretiert werden.)


danke Jon. Ich dachte, die Ergebniszeichenfolge würde genau der Formatzeichenfolge entsprechen. Ich werde Ihren Vorschlag versuchen.
Eldorado

3
Nur eine kleine Überlegung. Wenn Sie ein CultureInfo-Objekt aus einem bestimmten Code laden, empfehle ich immer, den useUserOverrideParameter auf false zu setzen, da sonst einige Benutzereinstellungen die Kultureinstellungen überschreiben können. Zum Beispiel schlage ich in Ihrem Fall vor, new zu verwenden CultureInfo("ar-SA", false).
Davide Icardi

@ DavidIcardi: Interessant, danke - obwohl in diesem Fall der Zweck der Verwendung von Saudi-Arabien speziell darin bestand, zu sagen, warum die Verwendung der invarianten Kultur wahrscheinlich richtig ist. Wird dies jedoch für zukünftige Beiträge berücksichtigen.
Jon Skeet

7
Auf halbem Weg nach dieser ausführlichen Antwort fragte ich mich: Wäre das wieder Jon? Ja.
Grimasse der Verzweiflung

Wie verwalte ich dasselbe mit Html.TextBoxFor (x => x.Date, "{0: MM / tt / jjjj}")?
VISHMAY

9

:hat eine besondere Bedeutung: Es ist das Zeittrennzeichen. ( Benutzerdefinierte Zeichenfolgen für Datums- und Zeitformat ).

Verwenden Sie \, um es zu entkommen:

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

Oder verwenden Sie CultureInfo.InvariantCulture:

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

Ich würde vorschlagen, mit dem zweiten zu gehen, da es auch /eine besondere Bedeutung hat (es ist das Datumstrennzeichen ), so dass Sie auch damit Probleme haben können.


2
Es ist nicht nur das Datumstrennzeichen ein Problem - siehe meine Antwort für ein Beispiel der Kultur, die sich auch auf die tatsächlichen Zahlen auswirkt ...
Jon Skeet

1
entkommt ihm nicht!
Shereef Marzouk

8

Sie können InvariantCulture verwenden, da sich Ihr Benutzer in einer Kultur befinden muss, in der ein Punkt anstelle eines Doppelpunkts verwendet wird:

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

7

Ich bin in letzter Zeit mit Windows 10 aus einer anderen Richtung auf dieses Problem gestoßen und fand die Antwort von @JonSkeet sehr hilfreich bei der Lösung meines Problems.

Ich habe auch einige weitere Nachforschungen mit einem Testformular angestellt und festgestellt, dass der ToString-Aufruf ("JJJJ-MM-TT HH: MM: SS") in Windows 7 und anders reagierte , wenn die aktuelle Kultur auf "no"oder "nb-NO"zur Laufzeit ( Thread.CurrentThread.CurrentCulture = new CultureInfo("no");) eingestellt war Windows 10. Es gab zurück, was ich in Windows 7 und HH.mm.ss in Windows 10 erwartet hatte!

Ich finde das ein bisschen gruselig! Da ich glaubte, dass eine Kultur zumindest in jeder Windows-Version eine Kultur ist.


Ich wäre sehr gespannt, was das wirklich verursacht.
Lauri Peltonen

2
Es wurde als Windows 10-Lokalisierungsfehler erkannt und behoben. Ein Windows-Update auf dem Client-Computer behebt das Problem. Weitere Details finden Sie in diesem Blog-Beitrag: heikniemi.net/hardcoded/2015/08/…
Håkon Seljåsen

Der Blog von Jouni Heikniemi, auf den ich oben verlinkt habe, scheint kaputt zu sein. Relevante Windows-Updates, bei denen die Probleme behoben wurden, wurden dort aufgelistet: 2015-10-09: KB3093266 - Windows 10 KB3088956 - Windows Server 2012 R2 und Windows 8.1 KB3088955 - Windows Server 2012 und Windows 8 KB3088957 - Windows 7 SP1, Windows Server 2008 SP2 , Windows Server 2008 R2 SP1 und Windows Vista SP2 Versuchen Sie erneut, eine Verknüpfung zum Blog herzustellen
Håkon Seljåsen

4

Sie können String.Format verwenden:

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

Datum in Zeichenfolge konvertieren

Verwenden Sie den Namen Space

using System.Globalization;

Code

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

So konvertieren Sie ein Datum nicht in eine Zeichenfolge. Parsing ist das Gegenteil!
Vincent Vancalbergh
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.