Frage

[ Aktualisieren : Formatangaben sind nicht dasselbe wie Formatstrings; ein Formatbezeichner ist ein Stück eines benutzerdefinierten Format-String, in dem ein Format-String ‚Bestand‘ ist und die Anpassung nicht geben. Mein Problem ist, mit Planern nicht Formate ]

Ich habe versucht, Folgendes zu bieten: Datetime-Konvertierungen mit einem Format-String auszuführen, die ‚zzz‘ Formatbezeichner verwendet, die ich kenne, in der lokalen Zeit gebunden. Also, wenn ich mit einer UTC-Datum Zeit Rundfahrt versuche, wirft es eine DateTimeInvalidLocalFormat Ausnahme, die es sein sollte, mit diesem Text:

A UTC Datetime wird in einem Format in Text umgewandelt, die für die lokalen Zeiten nur korrekt ist. Dies kann passieren, wenn DateTime.ToString mit dem ‚z‘ Formatspezifizierer Aufruf, die eine lokale Zeitzone Offset in der Ausgabe enthalten wird. In diesem Fall entweder die ‚Z‘ Formatangabe, die eine UTC-Zeit , oder verwenden Sie den ‚o‘ Format-String bezeichnet, die die empfohlene Methode ist ein Datetime in Text bestehen bleiben. Dies kann auch auftreten, wenn ein Datetime vorbei XmlConvert oder DataSet serialisiert werden. Bei der Verwendung von XmlConvert.ToString, übergibt in XmlDateTimeSerializationMode.RoundtripKind korrekt serialisiert werden. Bei der Verwendung von Datasets, stellen Sie die Datetime auf dem Datacolumn Objekt DataSetDateTime.Utc.

auf diesem Vorschlag Basierend, alles, was ich tun müssen, um meinen Code zur Arbeit zu bekommen ist ‚zzz‘ mit ‚ZZZ‘ zu ersetzen, so kann ich in einem UTC-Format stehe. Das Problem ist, ‚Z‘ ist nicht überall in der Dokumentation und jeder ‚Z‘ Formatkombination Ich versuche, das heißt ‚Z‘, ‚ZZ‘, ‚ZZZ‘ gefunden, immer wandelt nur die Datetime-Instanz mit jenen wie Literale behandelt Zs .

Hat jemand vergessen, ohne zu sagen die Ausnahmemeldung Autor ‚Z‘ zu implementieren, oder ist ich fehle, wie eine gültige Ortszeit mit „+0000“ Offset tauschen, ohne Hacking?

Code-Beispiel:

// This is the format with 'zzzzz' representing local time offset
const string format = "ddd MMM dd HH:mm:ss zzzzz yyyy";

// create a UTC time
const string expected = "Fri Dec 19 17:24:18 +0000 2008";
var time = new DateTime(2008, 12, 19, 17, 24, 18, 0, DateTimeKind.Utc);

// If you're using a debugger this will rightfully throw an exception
// with .NET 3.5 SP1 because 'z' is for local time only; however, the exception
// asks me to use the 'Z' specifier for UTC times, but it doesn't exist, so it
// just spits out 'Z' as a literal.
var actual = time.ToString(format, CultureInfo.InvariantCulture);

Assert.AreEqual(expected, actual);
War es hilfreich?

Lösung

Vielleicht wäre die „K“ Formatbezeichner von Nutzen sein. Dies ist der einzige, der die Verwendung des Kapitals „Z“ zu erwähnen scheint.

„Z“ ist eine Art von einem einzigartigen Fall für Datetime. Die wörtliche „Z“ ist eigentlich ein Teil des ISO 8601 Datetime-Standard für die UTC-Zeiten. Wenn „Z“ (Zulu) am Ende einer Zeit geheftet ist, zeigt es an, dass die Zeit UTC, also wirklich die wörtlichen Z ist Teil der Zeit. Dies schafft wahrscheinlich ein paar Probleme für das Datumsformat Bibliothek in .NET, da es eigentlich ein wörtlichen, sondern als ein Formatbezeichner.

Andere Tipps

Wenn Sie Datetime verwenden Sie können ein Datum und eine Zeit in einer Variablen speichern.

Das Datum kann eine lokale Zeit oder UTC-Zeit sein, es hängt von Ihnen ab.

Zum Beispiel, ich bin in Italien (2 UTC)

var dt1 = new DateTime(2011, 6, 27, 12, 0, 0); // store 2011-06-27 12:00:00
var dt2 = dt1.ToUniversalTime()  // store 2011-06-27 10:00:00

Also, was passiert, wenn ich DT1 und DT2 einschließlich der Zeitzone drucken?

dt1.ToString("MM/dd/yyyy hh:mm:ss z") 
// Compiler alert...
// Output: 06/27/2011 12:00:00 +2

dt2.ToString("MM/dd/yyyy hh:mm:ss z") 
// Compiler alert...
// Output: 06/27/2011 10:00:00 +2

DT1 und DT2 enthalten nur ein Datum und eine Uhrzeit. DT1 und DT2 enthalten nicht die Zeitzone gegenüber.

So, wo die "2" kommen aus wenn es nicht in der DT1 und DT2 Variablen enthalten?

Es kommt von Ihrer Computer Uhreinstellung.

Der Compiler sagt Ihnen, dass, wenn Sie die ‚zzz‘ Format verwenden Sie eine Zeichenfolge schreiben, die „DATE + TIME“ (das sind Speicher in DT1 und DT2) kombinieren + „Zeitverschiebung“ (das nicht ist enthalten in DT1 und DT2, weil sie DateTyme Typ) und es wird verwenden den Offset der Server-Maschine, dass es die Ausführung des Codes.

sind

Der Compiler sagen Sie „Warnung: die Ausgabe des Codes ist abhängig von der Maschinentakt-Offset“

Wenn ich diesen Code ausführen auf einem Server, der in London (+1 UTC) das Ergebnis positioniert ist, wird komplett anders: statt " 2 " wird es schreiben „ 1 "

...
dt1.ToString("MM/dd/yyyy hh:mm:ss z") 
// Output: 06/27/2011 12:00:00 +1

dt2.ToString("MM/dd/yyyy hh:mm:ss z") 
// Output: 06/27/2011 10:00:00 +1

Die richtige Lösung ist Datetimedatentyp anstelle von Datetime zu verwenden. Es ist in SQL Server verfügbar ab der Version 2008 beginnen und in .NET Framework ab der Version 3.5

Runddaten durch Zeichenketten Auslösung war schon immer ein Schmerz ... aber die docs, um anzuzeigen, dass die ‚o‘ spezifizierer ist derjenige für Round Tripping zu verwenden, die die UTC-Zustand erfasst. Wenn analysiert wird das Ergebnis in der Regel Art == Utc hat, wenn die ursprünglichen UTC ist. Ich habe festgestellt, dass das Beste, was zu tun, um immer Daten zu normalisieren entweder UTC oder lokaler vor der Serialisierung dann anweisen, den Parser auf, die Sie Normalisierung gewählt haben.

DateTime now = DateTime.Now;
DateTime utcNow = now.ToUniversalTime();

string nowStr = now.ToString( "o" );
string utcNowStr = utcNow.ToString( "o" );

now = DateTime.Parse( nowStr );
utcNow = DateTime.Parse( nowStr, null, DateTimeStyles.AdjustToUniversal );

Debug.Assert( now == utcNow );

Diese Seite auf MSDN listet Standard-Strings Datums- und Uhrzeitformat, uncluding Strings, die 'Z' verwendet wird.

Update: Sie müssen sicherstellen, dass der Rest der Datumszeichenfolge als auch das richtige Muster folgt (Sie nicht ein Beispiel geliefert haben, was Sie es senden, so ist es schwer zu sagen, ob du getan hast oder nicht). Für das UTC-Format es so aussehen funktionieren soll:

// yyyy'-'MM'-'dd HH':'mm':'ss'Z'
DateTime utcTime = DateTime.Parse("2009-05-07 08:17:25Z");
Label1.Text = dt.ToString("dd MMM yyyy | hh:mm | ff | zzz | zz | z");

AUSGABE:

07 Mai 2009 | 08:16 | 13 | +02:00 | +02 | +2

Ich bin in Dänemark, meine Offset von GMT +2 Stunden Hexe korrekt ist.

Wenn Sie die erhalten CLIENT Offset , empfehle ich, dass Sie überprüfen Trick , dass ich es tat. Die Seite wird in einem Server in Großbritannien, wo GMT +00:. 00 und, wie Sie sehen können Sie Ihre lokale GMT Offset erhalten


Im Hinblick auf Sie einen Kommentar, ich habe:

DateTime dt1 = DateTime.Now;
DateTime dt2 = dt1.ToUniversalTime();

Label1.Text = dt1.ToString("dd MMM yyyy | hh:mm | ff | zzz | zz | z");
Label2.Text = dt2.ToString("dd MMM yyyy | hh:mm | FF | ZZZ | ZZ | Z");

und ich bekomme diese:

07 Mai 2009 | 08:24 | 14 | +02:00 | +02 | +2
07 Mai 2009 | 06:24 | 14 | ZZZ | ZZ | Z 

ich keine Ausnahme erhalten, nur ... es tut nichts mit Kapital Z: (

Es tut mir leid, aber bin ich etwas fehlt?


Sie sorgfältig die MSDN Lesen auf Benutzerdefinierte Datums- und Zeitformatstrings

gibt es keine Unterstützung für Groß 'Z'.

ich es zu tun hatte mit DateTimeOffset und leider das "o" druckt "+0000" nicht "Z".

So landete ich mit:

dateTimeOffset.UtcDateTime.ToString("o")
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top