Konwertuj datę i godzinę? sznurka

11

Chcę przekonwertować DateTime?ciąg na. Jeżeli data jest null następnie powrócić "", jeszcze zwrócić format string tak: "2020-03-05T07:52:59.665Z". Kod jest mniej więcej taki, ale nie działa. Powiedział, "DateTime?"że nie zawierają definicji „ToUniversalTime”. Ktoś wie, jak to naprawić?

DateTime? date = DateTime.UtcNow;

var dateInUTCString = date == null ? "" : date.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");
Camahe
źródło
1
Nawiasem mówiąc, po prostu chcesz .ToString("o")?
John
Och, już korzystam z DateTime.UTCNow, więc nie muszę już używać ToUniversalTime ()? @Jan. Ach, rozumiem, .ToString("o")będę badał więcej. Dziękuję Ci!
camahe
1
Rzeczywiście, i zakładając, że chcesz tylko formatu ISO8601, możesz użyć „o”. Zobacz dokumenty
John
@John: „o” używa precyzji zaznaczania, co może nie być pożądane, nawet jeśli jest zgodne z ISO-8601.
Jon Skeet
1
„Ale kiedy używam .ToString („ o ”), nie ma on Z” - będzie, jeśli nadal wywołujesz ToUniversalTime (); „Z” pochodzi od tego, że ma rodzaj UTC.
Jon Skeet

Odpowiedzi:

16

Data i godzina? ma właściwość Value i właściwość HasValue

Próbować:

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

Możesz użyć krótkiej wersji:

var dateInUTCString = date?.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'") ?? "";
Leszek Mazur
źródło
8

Chociaż możesz użyć Valuewłaściwości bezpośrednio zgodnie z odpowiedzią Leszka, prawdopodobnie użyłbym operatora zerowo-warunkowego w połączeniu z operatorem zerowo-koalescencyjnym:

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

W tym przypadku ?.wynik będzie po prostu wartością zerową, jeśli datejest zerowy, a ??operator poda wartość domyślną, jeśli wynik date?.ToUniversalTime().ToString(...)wywołania jest zerowy (co nastąpiłoby tylko, jeśli datejest zerowy).

Zauważ, że naprawdę chcesz określić niezmienną kulturę, aby uniknąć nieoczekiwanych rezultatów, gdy kultura bieżącego wątku nie korzysta z kalendarza gregoriańskiego i nie musisz cytować wszystkich tych literałów w ciągu formatu. Z pewnością działa, gdy to robisz, ale trudniej jest odczytać IMO.

Jeśli nie przeszkadza ci, ile precyzji jest wyrażana w ciągu, możesz uprościć kod, używając standardowego ciągu formatu „O” :

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

W tym momencie nie musisz określać, CultureInfo.InvariantCultureponieważ zawsze jest używane przez „O”.

Jon Skeet
źródło
1
Dlaczego nie użyć "O"jako ciągu formatu? docs.microsoft.com/en-us/dotnet/standard/base-types/…
Zohar Peled
1
@ZoharPeled: To ma precyzję tykania, a PO najwyraźniej chce tylko precyzji milisekundowej.
Jon Skeet
Właściwie chcę format, który ma Zna końcu łańcucha
camahe
1
@camahe: Specyfikator formatu „O” już tego używa - patrz łącze do dokumentacji opublikowane przez Zohara. Jeśli naprawdę nie przeszkadza ci, ile cyfr dostaniesz, użycie „O” byłoby o wiele prostsze - nie musisz w tym przypadku podawać CultureInfo.InvariantCulture. Zmieni odpowiedź, aby dodać ją jako opcję.
Jon Skeet
2
@camahe: Proszę wyciągnąć z tego lekcję, że kiedy zadajesz pytanie, pomaga to być bardzo precyzyjne w twoich wymaganiach.
Jon Skeet