DateTime konvertieren? zu bespannen

11

Ich möchte einen DateTime?in einen String konvertieren . Wenn ein Datum null ist, geben Sie es zurück "", andernfalls geben Sie ein Zeichenfolgenformat wie das folgende zurück : "2020-03-05T07:52:59.665Z". Der Code ist ungefähr so, aber er funktioniert nicht. Es heißt "DateTime?", keine Definition für "ToUniversalTime" enthalten. Weiß jemand, wie man das behebt?

DateTime? date = DateTime.UtcNow;

var dateInUTCString = date == null ? "" : date.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");
camahe
quelle
1
Willst du übrigens nur .ToString("o")?
John
Oh, ich verwende DateTime.UTCNow bereits, sodass ich ToUniversalTime () nicht mehr verwenden muss. @John. Ah .ToString("o"), ich verstehe, ich werde mehr recherchieren. Vielen Dank!
Camahe
1
In der Tat können Sie "o" verwenden, vorausgesetzt, Sie möchten nur ein ISO8601-Format. Siehe die Dokumente
John
@ John: "o" verwendet Tick-Präzision, was möglicherweise nicht wünschenswert ist, obwohl es ISO-8601-konform ist.
Jon Skeet
1
"Aber wenn ich .ToString (" o ") verwende, hat es kein Z" - es wird, wenn Sie immer noch ToUniversalTime () aufrufen; Das 'Z' kommt von einer Art UTC.
Jon Skeet

Antworten:

16

Die DateTime? hat eine Value-Eigenschaft und eine HasValue-Eigenschaft

Versuchen:

var dateInUTCString = date.HasValue ? date.Value.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'") : "";

Sie können eine Kurzversion verwenden:

var dateInUTCString = date?.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'") ?? "";
Leszek Mazur
quelle
8

Während Sie die ValueEigenschaft gemäß Leszeks Antwort direkt verwenden können, würde ich wahrscheinlich den nullbedingten Operator in Verbindung mit dem nullkoaleszierenden Operator verwenden:

string dateInUTCString =
    date?.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture) 
    ?? "";

Hier führt der ?.nur zu einem Nullwert, wenn er datenull ist, und der ??Operator gibt einen Standardwert an, wenn das Ergebnis des date?.ToUniversalTime().ToString(...)Aufrufs null ist (was nur passieren würde, wenn datenull ist).

Beachten Sie, dass Sie die invariante Kultur wirklich angeben möchten, um unerwartete Ergebnisse zu vermeiden, wenn die Kultur des aktuellen Threads nicht den Gregorianischen Kalender verwendet und Sie nicht alle diese Literale in der Formatzeichenfolge zitieren müssen. Es funktioniert sicherlich, wenn Sie dies tun, aber es ist schwieriger, IMO zu lesen.

Wenn es Ihnen nichts ausmacht, wie genau die Zeichenfolge ist, können Sie den Code mithilfe der Zeichenfolge im Standardformat "O" vereinfachen :

string dateInUTCString = date?.ToUniversalTime().ToString("O") ?? "";

An diesem Punkt müssen Sie nicht angeben, CultureInfo.InvariantCultureda dies immer von "O" verwendet wird.

Jon Skeet
quelle
1
Warum nicht "O"als Formatzeichenfolge verwenden? docs.microsoft.com/en-us/dotnet/standard/base-types/…
Zohar Peled
1
@ZoharPeled: Das hat Tick-Präzision, und das OP will anscheinend nur Millisekunden-Präzision.
Jon Skeet
Eigentlich möchte ich ein Format, das Zam Ende der Zeichenfolge steht
camahe
1
@camahe: Der Formatbezeichner "O" verwendet dies bereits - siehe den von Zohar veröffentlichten Dokumentationslink. Wenn es Ihnen wirklich nichts ausmacht, wie viele Stellen Genauigkeit Sie erhalten, wäre die Verwendung von "O" viel einfacher - auch in diesem Fall müssten Sie CultureInfo.InvariantCulture nicht angeben. Ändert die Antwort, um sie als Option hinzuzufügen.
Jon Skeet
2
@camahe: Bitte nehmen Sie eine Lektion daraus , dass , wenn Sie eine Frage stellen, es zu sein , hilft wirklich in Ihren Anforderungen genau.
Jon Skeet