Converter DateTime? para sequenciar

11

Eu quero converter um DateTime?para string. Se uma data é nulo depois voltar "", senão retornar um formato de seqüência como esta: "2020-03-05T07:52:59.665Z". O código é algo como isto, mas não funciona. Ele disse "DateTime?"que não contém uma definição para "ToUniversalTime". Alguém sabe como consertar isso?

DateTime? date = DateTime.UtcNow;

var dateInUTCString = date == null ? "" : date.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");
camahe
fonte
11
A propósito, você só quer .ToString("o")?
João
Ah, eu já uso DateTime.UTCNow, então não preciso mais usar ToUniversalTime ()? @John. Ah entendo, .ToString("o")vou pesquisar mais. Obrigado!
camahe 5/03
11
De fato, e supondo que você queira apenas um formato ISO8601, você pode usar "o". Veja os documentos
John
@ John: "o" usa precisão de ticks, o que pode não ser desejável, mesmo que seja compatível com ISO-8601.
Jon Skeet
11
"Mas quando eu uso .ToString (" o "), ele não possui Z" - será o caso se você ainda chamar ToUniversalTime (); o 'Z' vem dele com um tipo de UTC.
Jon Skeet

Respostas:

16

O DateTime? tem uma propriedade Value e uma propriedade HasValue

Tentar:

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

Você pode usar a versão curta:

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

Embora você possa usar a Valuepropriedade diretamente, de acordo com a resposta de Leszek, provavelmente usaria o operador nulo-condicional em conjunto com o operador nulo-coalescente:

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

Aqui, o ?.resultado será apenas um valor nulo se datefor nulo, e o ??operador fornecerá um valor padrão se o resultado da date?.ToUniversalTime().ToString(...)chamada for nulo (o que aconteceria apenas se datefor nulo).

Observe que você realmente deseja especificar a cultura invariável para evitar resultados inesperados quando a cultura do encadeamento atual não usa o calendário gregoriano e não precisa citar todos esses literais na string de formato. Certamente funciona quando você faz isso, mas é mais difícil ler o IMO.

Se você não se importa com a precisão expressa na string, pode simplificar o código usando a string de formato padrão "O" :

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

Nesse ponto, você não precisa especificar, CultureInfo.InvariantCulturepois isso é sempre usado por "O".

Jon Skeet
fonte
11
Por que não usar "O"como uma string de formato? docs.microsoft.com/en-us/dotnet/standard/base-types/…
Zohar Peled
11
@ZoharPeled: Isso tem precisão de ticks, e o OP aparentemente só quer precisão de milissegundos.
Jon Skeet
Na verdade, eu quero um formato que tenha Zno final da string
camahe
11
@camahe: O especificador de formato "O" já usa isso - veja o link da documentação que o Zohar postou. Se você realmente não se importa com quantos dígitos de precisão obtém, usar "O" seria muito mais simples - você não precisaria especificar CultureInfo.InvariantCulture nesse caso. Irá alterar a resposta para adicionar isso como uma opção.
Jon Skeet
2
@camahe: Por favor, tire uma lição disso que, quando você faz uma pergunta, ajuda a ser realmente preciso em suas necessidades.
Jon Skeet