Dado um objeto DateTime, como obtenho uma data ISO 8601 no formato de string?

790

Dado:

DateTime.UtcNow

Como obtenho uma string que representa o mesmo valor em um formato compatível com ISO 8601 ?

Observe que a ISO 8601 define vários formatos semelhantes. O formato específico que estou procurando é:

yyyy-MM-ddTHH:mm:ssZ
Iain
fonte

Respostas:

780

Nota para os leitores: Vários comentaristas apontaram alguns problemas nesta resposta (relacionados principalmente à primeira sugestão). Consulte a seção de comentários para obter mais informações.

DateTime.UtcNow.ToString("yyyy-MM-ddTHH\\:mm\\:ss.fffffffzzz");

Isso fornece uma data semelhante a 2008-09-22T13: 57: 31.2311892-04: 00 .

Outra maneira é:

DateTime.UtcNow.ToString("o");

que lhe dá 2008-09-22T14: 01: 54.9571247Z

Para obter o formato especificado, você pode usar:

DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")

Opções de formatação DateTime

Wayne
fonte
20
Hoje em dia, fazer isso (tentando renderizar um horário UTC com um deslocamento, o que não faz muito sentido) gera uma exceção. Então, eu concordo com os outros que o formato "s" com a cultura invariável é provavelmente mais correto. Para sua informação, a mensagem do formatexception é: "Um UTC DateTime está sendo convertido em texto em um formato que é correto apenas para horários locais. Isso pode acontecer ao chamar DateTime.ToString usando o especificador de formato 'z', que incluirá um deslocamento de fuso horário local na saída ".
Tom Lianza
9
Eu moro na Austrália, e para mim eu tive que usar ToString("yyyy-MM-ddTHH:mm:ssK")para isso funcionar (com o plugin jquery timeago que eu estava usando).
GONeale
6
Se você deseja incluir o deslocamento do fuso horário, faça o seguinte: dt.ToString("s") + dt.ToString("zzz")// 2013-12-05T07: 19: 04-08: 00
alekop
4
As barras (\ :) causam problemas com a string ... coloque um caractere @ para usar uma literal de string.
Gigi
6
@core: esse é um dos formatos padrão, que é diferente dos formatos personalizados vinculados: msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
Wayne
361

DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture)deve fornecer o que você está procurando, pois o especificador de formato "s" é descrito como um padrão de data / hora classificável; está em conformidade com a ISO 8601.

Simon Wilson
fonte
34
Eu acredito que esta é a resposta correta. Não faz sentido definir explicitamente o aaaa-MM-etc, se a Microsoft já implementou a ISO 8601. A resposta de Iain também estava certa, mas você sempre deve especificar InvariantCulture (ou qualquer outro CultureInfo) por vários motivos (por exemplo, nunca assuma que o .NET deva apenas assuma). Você também pode usar: DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.SortableDateTimePattern); No entanto, uma vez que todos estes excluir o fuso horário, etc., você pode ter escolha a não ser usar o formatador explícita, ou seja"yyyy-MM-ddTHH:mm:ss.fffZ"
Jon Davis
20
Enquanto está em conformidade, deixa de fora o fuso horário, Zassim: DateTime.UtcNow.ToString(c, CultureInfo.InvariantCulture)) => 2012-06-26T11:55:36e não há uma resolução de milissegundos que é muito boa de ter, já que os computadores fazem um número razoável de ticks por segundo.
Henrik
9
Com oo 2012-06-26T11:55:36.1007668Zsignificado dos 36.1007668segundos, você obtém a resolução de até 1/10^7um segundo. De ISO8601: 2004If a decimal fraction is included, lower order time elements (if any) shall be omitted and the decimal fraction shall be divided from the integer part by the decimal sign [...] the comma (,) or full stop (.)
Henrik
2
@binki - agora estou muito confuso. De acordo com a documentação que eu vinculei anteriormente para SortableDateTimePattern , ele diz que deve ser específico da cultura. No entanto, parece ser contrariado por seus próprios exemplos (já que todos parecem iguais); tente DateTime.Now.ToString("s", new CultureInfo(myCulture)).
drzaus
87
DateTime.UtcNow.ToString("s")

Retorna algo como 2008-04-10T06: 30: 00

UtcNowobviamente, retorna um horário UTC para que não haja danos em:

string.Concat(DateTime.UtcNow.ToString("s"), "Z")
Iain
fonte
11
Apenas por interesse: Por que string.Concat () em vez de '+'?
Daniel Fortunov 22/09/08
2
Habbit, há alguma diferença?
Iain
84
@ KooZomers: Eu não acho que isso esteja correto. Eu acho que a + bcompila com o mesmo código intermediário que string.Concat(a, b)(assumindo que aeb são seqüências de caracteres, é claro), portanto não há diferença no desempenho ou no consumo de memória.
precisa
78
Sim, Mark está correto. Koen, você acabou de cair na armadilha de uma micro-otimização absurdamente prematura, mesmo que esteja correta.
Noldorin
7
@ greg84: Bem, você não está totalmente certo. Veja esta postagem do arquiteto da Microsoft Rico Mariani: blogs.msdn.com/b/ricom/archive/2003/12/15/43628.aspx - ele diz que a + b compila para concat + há mais algumas informações sobre o uso adequado de StringBuilder.
Mrówa 17/09/14
37

Usar:

private void TimeFormats()
{
    DateTime localTime = DateTime.Now;
    DateTime utcTime = DateTime.UtcNow;
    DateTimeOffset localTimeAndOffset = new DateTimeOffset(localTime, TimeZoneInfo.Local.GetUtcOffset(localTime));

    //UTC
    string strUtcTime_o = utcTime.ToString("o");
    string strUtcTime_s = utcTime.ToString("s");
    string strUtcTime_custom = utcTime.ToString("yyyy-MM-ddTHH:mm:ssK");

    //Local
    string strLocalTimeAndOffset_o = localTimeAndOffset.ToString("o");
    string strLocalTimeAndOffset_s = localTimeAndOffset.ToString("s");
    string strLocalTimeAndOffset_custom = utcTime.ToString("yyyy-MM-ddTHH:mm:ssK");

    //Output
    Response.Write("<br/>UTC<br/>");
    Response.Write("strUtcTime_o: " + strUtcTime_o + "<br/>");
    Response.Write("strUtcTime_s: " + strUtcTime_s + "<br/>");
    Response.Write("strUtcTime_custom: " + strUtcTime_custom + "<br/>");

    Response.Write("<br/>Local Time<br/>");
    Response.Write("strLocalTimeAndOffset_o: " + strLocalTimeAndOffset_o + "<br/>");
    Response.Write("strLocalTimeAndOffset_s: " + strLocalTimeAndOffset_s + "<br/>");
    Response.Write("strLocalTimeAndOffset_custom: " + strLocalTimeAndOffset_custom + "<br/>");

}

RESULTADO

UTC
    strUtcTime_o: 2012-09-17T22:02:51.4021600Z
    strUtcTime_s: 2012-09-17T22:02:51
    strUtcTime_custom: 2012-09-17T22:02:51Z

Local Time
    strLocalTimeAndOffset_o: 2012-09-17T15:02:51.4021600-07:00
    strLocalTimeAndOffset_s: 2012-09-17T15:02:51
    strLocalTimeAndOffset_custom: 2012-09-17T22:02:51Z

Fontes:

Don
fonte
2
parece que você é vítima de copiar nos costumes locais ;-) string strLocalTimeAndOffset_custom = localTimeAndOffset.ToString("yyyy-MM-ddTHH:mm:ssK");resultaria em:strLocalTimeAndOffset_custom: 2012-09-17T22:02:51-07:00
Holly
oé um formato ISO-8601.
Yousha Aleayoub
33
System.DateTime.UtcNow.ToString("o")

=>

val it : string = "2013-10-13T13:03:50.2950037Z"
Henrik
fonte
Concordou esta é a única maneira de ter certeza absoluta de que você tem uma data / hora inequívoca em qualquer fuso horário
Matt Wilko
23

Você pode obter o "Z" ( ISO 8601 UTC ) com o próximo código:

Dim tmpDate As DateTime = New DateTime(Now.Ticks, DateTimeKind.Utc)
Dim res as String = tmpDate.toString("o") '2009-06-15T13:45:30.0000000Z


Aqui está o porquê:

A ISO 8601 possui alguns formatos diferentes:

DateTimeKind.Local

2009-06-15T13:45:30.0000000-07:00

DateTimeKind.Utc

2009-06-15T13:45:30.0000000Z

DateTimeKind.Unspecified

2009-06-15T13:45:30.0000000


O .NET nos fornece uma enumeração com essas opções:

'2009-06-15T13:45:30.0000000-07:00
Dim strTmp1 As String = New DateTime(Now.Ticks, DateTimeKind.Local).ToString("o")

'2009-06-15T13:45:30.0000000Z
Dim strTmp2 As String = New DateTime(Now.Ticks, DateTimeKind.Utc).ToString("o")

'2009-06-15T13:45:30.0000000
Dim strTmp3 As String = New DateTime(Now.Ticks, DateTimeKind.Unspecified).ToString("o")

Nota : Se você aplicar o "utilitário de observação" do Visual Studio 2008 ao toString ("o") poderá obter resultados diferentes, não sei se é um erro, mas, nesse caso, você terá melhores resultados usando uma variável String se você estiver depurando.

Origem: Strings de formato de data e hora padrão (MSDN)

Oaxas
fonte
20

Se você deve usar o DateTime para ISO 8601, o ToString ("o") deve render o que você está procurando. Por exemplo,

2015-07-06T12:08:27

No entanto, o DateTime + TimeZone pode apresentar outros problemas, conforme descrito na postagem do blog DateTime e DateTimeOffset no .NET: Boas práticas e armadilhas comuns :

O DateTime possui inúmeras armadilhas criadas para fornecer erros de código:

1.- Os valores DateTime com DateTimeKind.Unspecified são más notícias.

2.- O DateTime não se importa com o UTC / Local ao fazer comparações.

3.- Os valores DateTime não conhecem as strings de formato padrão.

4.- A análise de uma string que possui um marcador UTC com DateTime não garante a hora UTC.

Alex Nolasco
fonte
2
ISO8601 é usado no strava para um. Uso No entanto, por favor: StartTime.ToString ( "AAAA-MM-DDThh: mm: ssZ") em vez de ToString ( "o"), que acrescenta milissegundos etc.
peterincumbria
2
Para mim, "aaaa-MM-dd-THH: mm: ssZ" literalmente exibiu "Z" no final da minha string em vez de um marcador de fuso horário, que não fez o que eu queria. ToString ("o") realmente fez o que eu precisava, muito mais fácil e mais curto.
Blair Connolly
18

Surpreendeu que ninguém o sugeriu:

System.DateTime.UtcNow.ToString("u").Replace(' ','T')
# Using PowerShell Core to demo

# Lowercase "u" format
[System.DateTime]::UtcNow.ToString("u")
> 2020-02-06 01:00:32Z

# Lowercase "u" format with replacement
[System.DateTime]::UtcNow.ToString("u").Replace(' ','T')
> 2020-02-06T01:00:32Z

O UniversalSortableDateTimePattern leva você até o que você deseja (que é mais uma representação da RFC 3339 ).


Adicionado: decidi usar os benchmarks que estavam em resposta https://stackoverflow.com/a/43793679/653058 para comparar o desempenho.

tl: dr; está no fim caro, mas ainda tem pouco mais de meio milissegundo no meu velho e ruim laptop :-)

Implementação:

[Benchmark]
public string ReplaceU()
{
   var text = dateTime.ToUniversalTime().ToString("u").Replace(' ', 'T');
   return text;
}

Resultados:

// * Summary *

BenchmarkDotNet=v0.11.5, OS=Windows 10.0.19002
Intel Xeon CPU E3-1245 v3 3.40GHz, 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.0.100
  [Host]     : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT
  DefaultJob : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT


|               Method |     Mean |     Error |    StdDev |
|--------------------- |---------:|----------:|----------:|
|           CustomDev1 | 562.4 ns | 11.135 ns | 10.936 ns |
|           CustomDev2 | 525.3 ns |  3.322 ns |  3.107 ns |
|     CustomDev2WithMS | 609.9 ns |  9.427 ns |  8.356 ns |
|              FormatO | 356.6 ns |  6.008 ns |  5.620 ns |
|              FormatS | 589.3 ns |  7.012 ns |  6.216 ns |
|       FormatS_Verify | 599.8 ns | 12.054 ns | 11.275 ns |
|        CustomFormatK | 549.3 ns |  4.911 ns |  4.594 ns |
| CustomFormatK_Verify | 539.9 ns |  2.917 ns |  2.436 ns |
|             ReplaceU | 615.5 ns | 12.313 ns | 11.517 ns |

// * Hints *
Outliers
  BenchmarkDateTimeFormat.CustomDev2WithMS: Default     -> 1 outlier  was  removed (668.16 ns)
  BenchmarkDateTimeFormat.FormatS: Default              -> 1 outlier  was  removed (621.28 ns)
  BenchmarkDateTimeFormat.CustomFormatK: Default        -> 1 outlier  was  detected (542.55 ns)
  BenchmarkDateTimeFormat.CustomFormatK_Verify: Default -> 2 outliers were removed (557.07 ns, 560.95 ns)

// * Legends *
  Mean   : Arithmetic mean of all measurements
  Error  : Half of 99.9% confidence interval
  StdDev : Standard deviation of all measurements
  1 ns   : 1 Nanosecond (0.000000001 sec)

// ***** BenchmarkRunner: End *****
rburte
fonte
1
A resposta aceita de "o" funciona, mas fornece uma quantidade irritante de precisão (geez .XXXXXXX segundos) enquanto eu prefiro isso, pois para em segundos.
Jhocking 06/06/19
Esse documento também afirma que "u" é ISO 8601, mas o que há com o espaço em vez de T? reuni-lo microsoft
jhocking 06/06/19
@jhocking en.wikipedia.org/wiki/ISO_8601#cite_note-30 ISO 8601 é relativamente permissivo se você lê-lo ...
rburte
16

Eu usaria apenas XmlConvert:

XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.RoundtripKind);

Ele preservará automaticamente o fuso horário.

Sumrak
fonte
Fui em frente e adicionei um método de extensão. classe estática pública DateTimeExtensions {string estática pública ToIsoFormat (this DateTime dateTime) {return XmlConvert.ToString (dateTime, XmlDateTimeSerializationMode.RoundtripKind); }}
muruge
14

A maioria dessas respostas possui milissegundos / microssegundos, o que claramente não é suportado pela ISO 8601. A resposta correta seria:

System.DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssK");
// or
System.DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK");

Referências:

Justin Turner
fonte
15
Leia o seu próprio link da Wikipedia em "Times". Ele menciona "frações decimais", o que significa que a ISO 8601 suporta milissegundos e microssegundos (mas as partes que se comunicam podem limitar o número de casas decimais aceitas).
Søren Boisen
11
DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss zzz");

DateTime.Now.ToString("O");

NOTA: Dependendo da conversão que você está fazendo, você estará usando a primeira linha (mais parecida) ou a segunda.

Certifique-se de aplicar o formato apenas no horário local, pois "zzz" é a informação de fuso horário para a conversão UTC.

imagem

PSM
fonte
Não tenho tanta certeza #ChrisHynes, pois ele está perguntando sobre a sugestão que fiz sobre a primeira linha de código, mas se você estiver correto e esse for o caso, a resposta será "ReSharper"
PSM
9

O "s"especificador de formato padrão representa uma cadeia de caracteres de formato de data e hora personalizada, definida pela propriedade DateTimeFormatInfo.SortableDateTimePattern . O padrão reflete um padrão definido ( ISO 8601 ) e a propriedade é somente leitura. Portanto, é sempre o mesmo, independentemente da cultura usada ou do provedor de formato fornecido. A sequência de formato personalizado é"yyyy'-'MM'-'dd'T'HH':'mm':'ss" .

Quando esse especificador de formato padrão é usado, a operação de formatação ou análise sempre usa a cultura invariável.

- do MSDN

Amal
fonte
1
Então está tudo bem em usar .ToString("s")?
AhmetB - Google
Eu acredito que sim. - Contanto que sua exigência corresponda à pergunta original que é .. Mas dê uma olhada no aviso de simon wilson abaixo
Amal
9

Para converter DateTime.UtcNow em uma representação de seqüência de aaaa-MM-ddTHH: mm: ssZ , você pode usar o método ToString () da estrutura DateTime com uma seqüência de formatação personalizada. Ao usar seqüências de caracteres de formato personalizado com um DateTime, é importante lembrar que você precisa escapar de seus separadores usando aspas simples.

A seguir, retornará a representação de string que você queria:

DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'", DateTimeFormatInfo.InvariantInfo)
Oposição
fonte
9

É interessante que o formato personalizado "aaaa-MM-ddTHH: mm: ssK" (sem ms) seja o método de formato mais rápido.

Também é interessante que o formato "S" seja lento no Classic e rápido no Core ...

É claro que os números são muito próximos, entre algumas linhas a diferença é insignificante (os testes com sufixo _Verifysão os mesmos que os que estão sem esse sufixo, demonstram a repetibilidade dos resultados)

BenchmarkDotNet=v0.10.5, OS=Windows 10.0.14393
Processor=Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), ProcessorCount=4
Frequency=3233539 Hz, Resolution=309.2587 ns, Timer=TSC
  [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
  Clr    : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
  Core   : .NET Core 4.6.25009.03, 64bit RyuJIT


               Method |  Job | Runtime |       Mean |     Error |    StdDev |     Median |        Min |        Max | Rank |  Gen 0 | Allocated |
--------------------- |----- |-------- |-----------:|----------:|----------:|-----------:|-----------:|-----------:|-----:|-------:|----------:|
           CustomDev1 |  Clr |     Clr | 1,089.0 ns | 22.179 ns | 20.746 ns | 1,079.9 ns | 1,068.9 ns | 1,133.2 ns |    8 | 0.1086 |     424 B |
           CustomDev2 |  Clr |     Clr | 1,032.3 ns | 19.897 ns | 21.289 ns | 1,024.7 ns | 1,000.3 ns | 1,072.0 ns |    7 | 0.1165 |     424 B |
     CustomDev2WithMS |  Clr |     Clr | 1,168.2 ns | 16.543 ns | 15.474 ns | 1,168.5 ns | 1,149.3 ns | 1,189.2 ns |   10 | 0.1625 |     592 B |
              FormatO |  Clr |     Clr | 1,563.7 ns | 31.244 ns | 54.721 ns | 1,532.5 ns | 1,497.8 ns | 1,703.5 ns |   14 | 0.2897 |     976 B |
              FormatS |  Clr |     Clr | 1,243.5 ns | 24.615 ns | 31.130 ns | 1,229.3 ns | 1,200.6 ns | 1,324.2 ns |   13 | 0.2865 |     984 B |
       FormatS_Verify |  Clr |     Clr | 1,217.6 ns | 11.486 ns | 10.744 ns | 1,216.2 ns | 1,205.5 ns | 1,244.3 ns |   12 | 0.2885 |     984 B |
        CustomFormatK |  Clr |     Clr |   912.2 ns | 17.915 ns | 18.398 ns |   916.6 ns |   878.3 ns |   934.1 ns |    4 | 0.0629 |     240 B |
 CustomFormatK_Verify |  Clr |     Clr |   894.0 ns |  3.877 ns |  3.626 ns |   893.8 ns |   885.1 ns |   900.0 ns |    3 | 0.0636 |     240 B |
           CustomDev1 | Core |    Core |   989.1 ns | 12.550 ns | 11.739 ns |   983.8 ns |   976.8 ns | 1,015.5 ns |    6 | 0.1101 |     423 B |
           CustomDev2 | Core |    Core |   964.3 ns | 18.826 ns | 23.809 ns |   954.1 ns |   935.5 ns | 1,015.6 ns |    5 | 0.1267 |     423 B |
     CustomDev2WithMS | Core |    Core | 1,136.0 ns | 21.914 ns | 27.714 ns | 1,138.1 ns | 1,099.9 ns | 1,200.2 ns |    9 | 0.1752 |     590 B |
              FormatO | Core |    Core | 1,201.5 ns | 16.262 ns | 15.211 ns | 1,202.3 ns | 1,178.2 ns | 1,225.5 ns |   11 | 0.0656 |     271 B |
              FormatS | Core |    Core |   993.5 ns | 19.272 ns | 24.372 ns |   999.4 ns |   954.2 ns | 1,029.5 ns |    6 | 0.0633 |     279 B |
       FormatS_Verify | Core |    Core | 1,003.1 ns | 17.577 ns | 16.442 ns | 1,009.2 ns |   976.1 ns | 1,024.3 ns |    6 | 0.0674 |     279 B |
        CustomFormatK | Core |    Core |   878.2 ns | 17.017 ns | 20.898 ns |   877.7 ns |   851.4 ns |   928.1 ns |    2 | 0.0555 |     215 B |
 CustomFormatK_Verify | Core |    Core |   863.6 ns |  3.968 ns |  3.712 ns |   863.0 ns |   858.6 ns |   870.8 ns |    1 | 0.0550 |     215 B |

Código:

    public class BenchmarkDateTimeFormat
    {
        public static DateTime dateTime = DateTime.Now;

        [Benchmark]
        public string CustomDev1()
        {
            var d = dateTime.ToUniversalTime();
            var sb = new StringBuilder(20);

            sb.Append(d.Year).Append("-");
            if (d.Month <= 9)
                sb.Append("0");
            sb.Append(d.Month).Append("-");
            if (d.Day <= 9)
                sb.Append("0");
            sb.Append(d.Day).Append("T");
            if (d.Hour <= 9)
                sb.Append("0");
            sb.Append(d.Hour).Append(":");
            if (d.Minute <= 9)
                sb.Append("0");
            sb.Append(d.Minute).Append(":");
            if (d.Second <= 9)
                sb.Append("0");
            sb.Append(d.Second).Append("Z");
            var text = sb.ToString();
            return text;
        }

        [Benchmark]
        public string CustomDev2()
        {
            var u = dateTime.ToUniversalTime();
            var sb = new StringBuilder(20);
            var y = u.Year;
            var d = u.Day;
            var M = u.Month;
            var h = u.Hour;
            var m = u.Minute;
            var s = u.Second;
            sb.Append(y).Append("-");
            if (M <= 9)
                sb.Append("0");
            sb.Append(M).Append("-");
            if (d <= 9)
                sb.Append("0");
            sb.Append(d).Append("T");
            if (h <= 9)
                sb.Append("0");
            sb.Append(h).Append(":");
            if (m <= 9)
                sb.Append("0");
            sb.Append(m).Append(":");
            if (s <= 9)
                sb.Append("0");
            sb.Append(s).Append("Z");
            var text = sb.ToString();
            return text;
        }

        [Benchmark]
        public string CustomDev2WithMS()
        {
            var u  = dateTime.ToUniversalTime();
            var sb = new StringBuilder(23);
            var y  = u.Year;
            var d  = u.Day;
            var M  = u.Month;
            var h  = u.Hour;
            var m  = u.Minute;
            var s  = u.Second;
            var ms = u.Millisecond;
            sb.Append(y).Append("-");
            if (M <= 9)
                sb.Append("0");
            sb.Append(M).Append("-");
            if (d <= 9)
                sb.Append("0");
            sb.Append(d).Append("T");
            if (h <= 9)
                sb.Append("0");
            sb.Append(h).Append(":");
            if (m <= 9)
                sb.Append("0");
            sb.Append(m).Append(":");
            if (s <= 9)
                sb.Append("0");
            sb.Append(s).Append(".");
            sb.Append(ms).Append("Z");
            var text = sb.ToString();
            return text;
        }
        [Benchmark]
        public string FormatO()
        {
            var text = dateTime.ToUniversalTime().ToString("o");
            return text;
        }
        [Benchmark]
        public string FormatS()
        {
            var text = string.Concat(dateTime.ToUniversalTime().ToString("s"),"Z");
            return text;
        }

        [Benchmark]
        public string FormatS_Verify()
        {
            var text = string.Concat(dateTime.ToUniversalTime().ToString("s"), "Z");
            return text;
        }

        [Benchmark]
        public string CustomFormatK()
        {
            var text = dateTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK");
            return text;
        }

        [Benchmark]
        public string CustomFormatK_Verify()
        {
            var text = dateTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK");
            return text;
        }
    }

https://github.com/dotnet/BenchmarkDotNet foi usado

Roman Pokrovskij
fonte
3

Usando o Newtonsoft.Json, você pode fazer

JsonConvert.SerializeObject(DateTime.UtcNow)

Exemplo: https://dotnetfiddle.net/O2xFSl

blackforest-tom
fonte
1
melhor resposta aqui.
The Integrator
2

Se você estiver desenvolvendo no SharePoint 2010 ou superior, poderá usar

using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
...
string strISODate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now)
Simon Logic
fonte
20
SharePoint, quando o seu .Net não é Java o suficiente.
Henrik
18
Usar o SharePoint para isso é como levar uma banheira de geleia, uma caixa de fósforos molhada e 2 chimpanzés que andam trapézios a um tiroteio.
Nathanchere
Mesmo no SharePoint, espero que você possa usar os BCLs, .ToString("o")ou melhor $"My complicated string {dt:o}".
binki
2

Para formatar como 2018-06-22T13: 04: 16 que pode ser passado no URI de uma API, use:

public static string FormatDateTime(DateTime dateTime)
{
    return dateTime.ToString("s", System.Globalization.CultureInfo.InvariantCulture);
}
Nick Gallimore
fonte
1
Eu acho que essa string de data ISO é invariável por definição.
Jonas
1

Como mencionado em outra resposta, DateTimetem problemas por design.

NodaTime

Sugiro usar o NodaTime para gerenciar valores de data / hora:

  • Hora local, data e hora
  • Tempo global
  • Hora com o fuso horário
  • Período
  • Duração

Formatação

Portanto, para criar e formatar, ZonedDateTimevocê pode usar o seguinte snippet de código:

var instant1 = Instant.FromUtc(2020, 06, 29, 10, 15, 22);

var utcZonedDateTime = new ZonedDateTime(instant1, DateTimeZone.Utc);
utcZonedDateTime.ToString("yyyy-MM-ddTHH:mm:ss'Z'", CultureInfo.InvariantCulture);
// 2020-06-29T10:15:22Z


var instant2 = Instant.FromDateTimeUtc(new DateTime(2020, 06, 29, 10, 15, 22, DateTimeKind.Utc));

var amsterdamZonedDateTime = new ZonedDateTime(instant2, DateTimeZoneProviders.Tzdb["Europe/Amsterdam"]);
amsterdamZonedDateTime.ToString("yyyy-MM-ddTHH:mm:ss'Z'", CultureInfo.InvariantCulture);
// 2020-06-29T12:15:22Z

Para mim, o NodaTimecódigo parece bem detalhado. Mas tipos são realmente úteis. Eles ajudam a lidar com os valores de data / hora corretamente.

Newtonsoft.Json

Para usar NodaTimecom Newtonsoft.Jsonvocê precisa adicionar referência a NodaTime.Serialization.JsonNetpacote NuGet e opções de configuração JSON.

services
    .AddMvc()
    .AddJsonOptions(options =>
    {
        var settings=options.SerializerSettings;
        settings.DateParseHandling = DateParseHandling.None;
        settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
    });
Vladimir Serykh
fonte