Convertir fecha y hora? Encadenar

11

Quiero convertir un DateTime?a cadena. Si una fecha es nulo luego regresar "", cosa devolver un formato de cadena como esta: "2020-03-05T07:52:59.665Z". El código es algo como esto pero no funcionará. Dijo "DateTime?"que no contienen una definición para "ToUniversalTime". Alguien sabe como arreglar esto?

DateTime? date = DateTime.UtcNow;

var dateInUTCString = date == null ? "" : date.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");
camahe
fuente
1
Por cierto, ¿solo quieres .ToString("o")?
John
Oh, ya uso DateTime.UTCNow, así que ya no necesito usar ToUniversalTime (). @Juan. Ah ya veo, .ToString("o")investigaré más. ¡Gracias!
Camahe
1
De hecho, y suponiendo que solo desea un formato ISO8601, puede usar "o". Ver los documentos
John
@John: "o" usa precisión de marca, lo que puede no ser deseable a pesar de que cumple con ISO-8601.
Jon Skeet
1
"Pero cuando uso .ToString (" o "), no tiene Z", lo hará si todavía llama a ToUniversalTime (); la 'Z' viene de tener un tipo de UTC.
Jon Skeet

Respuestas:

16

La fecha y hora? tiene una propiedad Value y una propiedad HasValue

Tratar:

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

Puedes usar la versión corta:

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

Si bien puede usar la Valuepropiedad directamente según la respuesta de Leszek, probablemente usaría el operador condicional nulo junto con el operador de fusión nula:

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

Aquí ?.solo dará como resultado un valor nulo si datees nulo, y el ??operador proporcionará un valor predeterminado si el resultado de la date?.ToUniversalTime().ToString(...)llamada es nulo (lo que solo sucedería si datees nulo).

Tenga en cuenta que realmente desea especificar la cultura invariante para evitar obtener resultados inesperados cuando la cultura del hilo actual no utiliza el calendario gregoriano, y no necesita citar todos esos literales en la cadena de formato. Ciertamente funciona cuando lo haces, pero es más difícil de leer IMO.

Si no le importa cuánta precisión se expresa en la cadena, puede simplificar el código utilizando la cadena de formato estándar "O" :

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

En ese punto no necesita especificar, CultureInfo.InvariantCultureya que siempre lo usa "O".

Jon Skeet
fuente
1
¿Por qué no usar "O"como una cadena de formato? docs.microsoft.com/en-us/dotnet/standard/base-types/…
Zohar
1
@ZoharPeled: Eso tiene precisión de tic, y el OP aparentemente solo quiere precisión de milisegundos.
Jon Skeet
En realidad quiero un formato que tenga Zal final de la cadena
camahe
1
@camahe: El especificador de formato "O" ya lo usa; vea el enlace de documentación que publicó Zohar. Si realmente no le importa cuántos dígitos de precisión obtiene, usar "O" sería mucho más simple: tampoco necesitaría especificar CultureInfo.InvariantCulture en ese caso. Modificará la respuesta para agregar eso como una opción.
Jon Skeet
2
@camahe: por favor, tome una lección de esto que cuando hace una pregunta, ayuda a ser realmente preciso en sus requisitos.
Jon Skeet