DateTime.ToString(format) transforma uma data em texto. O formato é uma string de formato padrão (uma única letra como d ou o, cujo padrão exato vem da cultura) ou um padrão personalizado montado com especificadores como yyyy, MM e HH. As mesmas strings funcionam na interpolação, $"{date:yyyy-MM-dd}", e em string.Format.
Saída:
2026-10-09
2026-10-09 18:30:07
09/10/2026
Oct 9, 2026
Friday, October 9
6:30 PM
18:30:07.045
Shipped 2026-10-09 at 18:30
Os exemplos desta página passam CultureInfo.InvariantCulture para que a saída seja a mesma em qualquer máquina; sem isso, ToString usa a cultura atual, que pode mudar os nomes dos meses, os separadores e até o calendário.
Especificadores de formato personalizados
Um formato personalizado é um padrão em que certas letras representam partes da data. Eles diferenciam maiúsculas de minúsculas: M é o mês e m é o minuto, H é a hora no formato de 24 horas e h no de 12 horas.
| Especificador | Significado | Exemplo para 2026-10-09 18:30:07.045 |
|---|---|---|
yyyy | Ano, 4 dígitos | 2026 |
yy | Ano, 2 dígitos | 26 |
MMMM | Nome completo do mês | October |
MMM | Nome abreviado do mês | Oct |
MM | Mês, 2 dígitos | 10 |
M | Mês, 1 ou 2 dígitos | 10 |
dddd | Nome completo do dia | Friday |
ddd | Nome abreviado do dia | Fri |
dd | Dia do mês, 2 dígitos | 09 |
d | Dia do mês, 1 ou 2 dígitos (em um padrão) | 9 |
HH | Hora, 00 a 23 | 18 |
H | Hora, 0 a 23 | 18 |
hh | Hora, 01 a 12 | 06 |
h | Hora, 1 a 12 | 6 |
mm | Minuto, 2 dígitos | 30 |
ss | Segundo, 2 dígitos | 07 |
fff | Milissegundos | 045 |
fffffff | Ticks (sete dígitos fracionários) | 0450000 |
tt | Indicador AM/PM | PM |
zzz | Deslocamento em relação ao UTC (DateTimeOffset ou hora local) | +02:00 |
K | Informação de fuso: Z, um deslocamento ou nada | Z (para um valor UTC) |
/ | O separador de data da cultura | / ou . ou - |
: | O separador de hora da cultura | : |
'text' ou \c | Texto ou caractere literal | 'at' |
Qualquer outro caractere é copiado como está. Isso inclui letras que não são especificadores, e é assim que "YYYY-DD" imprime YYYY-DD sem aviso: não existe especificador Y ou D maiúsculo no .NET.
Uma letra sozinha é lida como formato padrão, não personalizado: ToString("d") é o padrão de data curta, não o número do dia. Para pegar só o dia, escreva ToString("%d") ou use a propriedade Day.
Saída:
10/09/2026
9
20261009_183007
Week of Oct 9
18h30
2026-10-09T18:30:07
YYYY-DD
Strings de formato padrão
Formatos padrão são letras únicas cujo padrão real é definido pela cultura. Eles são a escolha certa para textos mostrados aos usuários, porque cada cultura recebe as próprias convenções de graça.
Saída:
d 10/09/2026
D Friday, 09 October 2026
f Friday, 09 October 2026 18:30
g 10/09/2026 18:30
G 10/09/2026 18:30:07
M October 09
Y 2026 October
t 18:30
T 18:30:07
o 2026-10-09T18:30:07.0000000Z
s 2026-10-09T18:30:07
u 2026-10-09 18:30:07Z
r Fri, 09 Oct 2026 18:30:07 GMT
en-US d: 10/9/2026, D: Friday, October 9, 2026
| Código | Nome | Depende da cultura? |
|---|---|---|
d / D | Data curta / longa | Sim |
t / T | Hora curta / longa | Sim |
f / F | Data longa com hora curta / longa | Sim |
g / G | Data curta com hora curta / longa | Sim |
M | Mês e dia | Sim |
Y | Ano e mês | Sim |
o | ISO 8601 de ida e volta, 7 dígitos fracionários, fuso | Não |
s | ISO 8601 ordenável, sem frações, sem fuso | Não |
u | Ordenável universal, termina em Z | Não |
r | RFC 1123, para cabeçalhos HTTP | Não |
o, s, u e r produzem o mesmo texto em qualquer cultura, o que os torna seguros para logs, nomes de arquivo e troca de dados. Repare que, em um DateTime, u e r não convertem o valor para UTC; eles o imprimem como está e o rotulam como UTC, então chame ToUniversalTime() antes (ou use DateTime.UtcNow) se o valor for local. (Em um DateTimeOffset eles convertem.)
A cultura muda a saída
Os formatos padrão, os nomes dos meses e dos dias e os separadores / e : vêm todos da cultura. Passe uma como segundo argumento de ToString:
Saída:
en-US 10/9/2026
en-GB 09/10/2026
de-DE 09.10.2026
fr-FR 09/10/2026
ja-JP 2026/10/09
Freitag, 9. Oktober 2026
vendredi 9 octobre 2026
09.10.2026
09/10/2026
Os dados de cultura não são fixos. O .NET no Linux e no macOS os lê da biblioteca ICU instalada no sistema, e desde o .NET 5 o .NET no Windows 10 em diante também (o .NET Framework usa os dados NLS do próprio Windows), então um padrão pode mudar um pouco entre versões e plataformas: versões recentes da ICU, por exemplo, colocam um espaço estreito não separável em vez de um espaço comum antes de "PM" no formato de hora curta dos EUA, e algumas dão datas curtas em espanhol sem o zero à esquerda. É mais um motivo para nunca converter de volta um texto formatado para exibição.
Daí vêm duas regras. Para textos que uma pessoa lê, formate com a cultura dela (em um servidor, a da requisição, não a do servidor) e prefira os formatos padrão, para que um leitor alemão veja 09.10.2026 e um leitor americano 10/9/2026. Para textos que um programa lê, use CultureInfo.InvariantCulture e um padrão sem ambiguidade como yyyy-MM-dd ou o. Uma data gravada com a cultura atual e lida em outra máquina é uma fonte clássica de dias e meses trocados.
ISO 8601 e ida e volta com "o"
O formato de ida e volta "o" grava todos os ticks mais a informação de fuso, então converter o texto de volta dá exatamente o mesmo DateTime, inclusive o Kind:
Saída:
2026-10-09T18:30:07.0450000Z
2026-10-09T18:30:07.0450000
2026-10-09T20:30:07.0000000+02:00
True
Utc
2026-10-09T18:30:07Z
2026-10-09 20:30 +02:00
O sufixo Z marca UTC; um DateTime com Kind Unspecified não recebe sufixo; uma hora local ou um DateTimeOffset recebe o deslocamento (+02:00). Converta com DateTimeStyles.RoundtripKind para que o Kind sobreviva. Serializadores JSON, bancos de dados e o Date do JavaScript leem esse formato.
Formatando TimeSpan
TimeSpan tem seu próprio conjunto, menor, de especificadores personalizados: d (dias), hh, mm, ss e fff. Ao contrário do DateTime, todo caractere literal, inclusive : e ., precisa ser escapado com uma barra invertida ou colocado entre aspas:
Saída:
1.03:25:09.1200000
1.03:25:09.1200000
03:25:09
1.03:25
25:09.120
27:25
hh em um formato de TimeSpan é o componente de horas (0 a 23), então uma duração de 27 horas é impressa como 03. Para totais acima de um dia, calcule a partir de TotalHours, como na última linha. elapsed.ToString("hh:mm") sem a barra invertida lança uma FormatException.
Erros comuns
mmpara o mês."yyyy-mm-dd"imprime os minutos no meio:2026-30-09. O mês éMM.hhsemtt."hh:mm"é um relógio de 12 horas sem AM nem PM, então 06:30 fica ambíguo. UseHHpara a hora de 24 horas.YYYYeDD. Não são especificadores no .NET; são impressos literalmente. Useyyyyedd./em um padrão para dados. É o separador de data da cultura. Coloque-o entre aspas ou use a cultura invariante.ToString()padrão em logs ou arquivos. O formato depende da máquina. Passe um formato e uma cultura.- Hora local rotulada como UTC.
"u","r"e um'Z'escrito à mão não convertem; converta antes. - Converter de volta com um padrão diferente do usado para escrever. Guarde as strings de formato de dados em uma única constante e use-a tanto com
ToStringquanto comParseExact.
Perguntas frequentes
Como formatar um DateTime como yyyy-MM-dd em C#?
date.ToString("yyyy-MM-dd") dá 2026-10-09. Em uma string interpolada, escreva $"{date:yyyy-MM-dd}". Acrescente " HH:mm:ss" para a hora no formato de 24 horas. Passe CultureInfo.InvariantCulture como segundo argumento quando o texto for para um arquivo ou outro programa, para que o calendário, os nomes dos meses e os separadores nunca dependam da máquina.
Qual a diferença entre mm e MM nos formatos de data em C#?
MM é o mês (01 a 12) e mm é o minuto (00 a 59). O formato diferencia maiúsculas de minúsculas, então yyyy-mm-dd imprime os minutos onde deveria estar o mês, um bug fácil de não perceber quando você olha um único valor. Da mesma forma, HH é a hora no formato de 24 horas e hh no de 12 horas.
Como formatar um DateTime em ISO 8601 em C#?
Use o formato de ida e volta "o": DateTime.UtcNow.ToString("o") dá 2026-10-09T18:30:07.0450000Z, com sete dígitos fracionários e um Z para UTC ou um deslocamento para horas locais. "s" dá a forma ordenável mais curta, sem frações nem fuso, e "yyyy-MM-ddTHH:mm:ssZ" é uma variante personalizada comum.
Como mostrar AM e PM em um formato de data em C#?
Use hh ou h para o relógio de 12 horas e tt para o indicador AM/PM: date.ToString("h:mm tt", CultureInfo.GetCultureInfo("en-US")) dá 6:30 PM. O indicador vem da cultura, e algumas culturas não têm nenhum, então passe uma cultura explicitamente quando precisar de AM e PM.
Por que meu formato de data mostra pontos em vez de barras?
Em uma string de formato, / não é uma barra literal, e sim o separador de data da cultura, e : é o separador de hora da cultura. Em uma máquina alemã, dd/MM/yyyy imprime 09.10.2026. Coloque o caractere entre aspas para forçá-lo, dd'/'MM'/'yyyy, ou formate com CultureInfo.InvariantCulture.