Como transformar DateTime em string ISO 8601 em C#? O problema que atormenta até os experientes
\n\nVocê já se deparou com uma situação em que sua API retorna uma data no formato "2023-01-15T10:30:00", e o cliente não a entende? Ou, ao contrário, você recebe uma data de um serviço externo, e ela parece "2023-01-15T10:30:00+03:00", e seu parser quebra? Familiar? Se você trabalha com C# e o objeto DateTime, a questão de obter uma string ISO 8601 é um clássico. No Stack Overflow, essa pergunta acumulou milhares de visualizações, e não é à toa. Hoje vamos entender de uma vez por todas como converter corretamente DateTime em string no formato ISO 8601, evitando as armadilhas típicas.
Não vamos apenas mostrar algumas linhas de código. Vamos analisar o formato C# DateTime para ISO 8601, abordar o trabalho com fusos horários, milissegundos e responder às perguntas mais frequentes. Vamos lá!
\n\nO que é ISO 8601 e por que é importante?
\n\nISO 8601 é um padrão internacional para representação de data e hora. Ele se parece com isto: 2023-12-25T14:30:00.0000000+03:00. Principais características:
- \n
- Separador T entre data e hora. \n
- Fuso horário é indicado no final (Z para UTC ou offset no formato +05:00). \n
- Parte fracionária dos segundos (milissegundos, ticks). \n
Por que isso é necessário? JSON, XML, REST API, bancos de dados — em todos os lugares onde é necessária uma transmissão inequívoca de um momento no tempo, sem vínculo com a cultura local do servidor. Formato incorreto — e seu parser do outro lado pode descartar as horas ou confundir o dia com o mês. Portanto, o formato de data ISO 8601 C# é uma habilidade obrigatória para qualquer desenvolvedor backend.
\n\nA maneira mais simples: DateTime.ToString() com o formato "o"
\n\nEm C#, existe um especificador de formato interno para o formato round-trip — é a letra "o" (minúscula). Ele fornece a string ISO 8601 completa com a máxima precisão.
\n\nDateTime now = DateTime.Now;\nstring isoString = now.ToString("o");\nConsole.WriteLine(isoString);\n// Exemplo de saída: 2023-12-25T14:30:00.1234567+03:00\n\nEsta é a maneira mais simples de obter uma string ISO 8601 em C#. Mas há uma ressalva: se seu DateTime tiver Kind = Unspecified, não haverá indicação de fuso horário no final da string. Isso pode ser um problema para parsers rigorosos. A solução é sempre usar DateTimeOffset ou definir explicitamente o Kind.
Como obter ISO 8601 sem milissegundos?
\n\nÀs vezes, milissegundos (ou mesmo ticks) não são necessários. Por exemplo, para logs ou datas simples. Use um formato personalizado:
\n\nDateTime now = DateTime.UtcNow;\nstring isoShort = now.ToString("yyyy-MM-ddTHH:mm:ssK");\nConsole.WriteLine(isoShort);\n// Exemplo: 2023-12-25T14:30:00Z\n\nAqui, K é o especificador de fuso horário. Para UTC, ele produz Z; para hora local, o offset.
Problema com fusos horários: DateTime vs DateTimeOffset
\n\nA principal dor dos desenvolvedores é a confusão entre DateTime e DateTimeOffset. Se você deseja obter uma data ISO 8601 em C# que seja interpretada de forma inequívoca em qualquer lugar do mundo, use DateTimeOffset. Ele sempre contém o offset do UTC.
\n\nDateTimeOffset nowOffset = DateTimeOffset.Now;\nstring isoOffset = nowOffset.ToString("o");\nConsole.WriteLine(isoOffset);\n// Exemplo: 2023-12-25T14:30:00.1234567+03:00\n\nSe você estiver trabalhando com DateTime, sempre verifique sua propriedade Kind:
- \n
DateTimeKind.Utc— produzZno final. \n DateTimeKind.Local— produz o offset local (por exemplo, +03:00). \n DateTimeKind.Unspecified— não produz nada