Analisar cadeias de caracteres de data e hora no .NET

A análise de cadeias de caracteres para convertê-las em objetos DateTime exige que você especifique as informações de como as datas e horas são representadas como texto. Diferentes culturas usam ordens diferentes para dia, mês e ano. Algumas representações usam o relógio de 24 horas, outras especificam "AM" e "PM". Alguns aplicativos precisam somente da data. Outros precisam apenas da hora. Há também outros que precisam especificar tanto a data quanto a hora. Os métodos que convertem cadeias de caracteres em objetos DateTime permitem que você forneça informações detalhadas sobre os formatos esperados e os elementos de uma data e hora que seu aplicativo precisa. Há três subtarefas para converter corretamente o texto em um DateTime:

  1. Você deve especificar o formato esperado do texto que representa a data e hora.
  2. Você pode especificar a cultura para o formato de data/hora.
  3. É possível especificar como os componentes ausentes na representação de texto serão definidos na data e hora.

Os métodos Parse e TryParse convertem muitas representações comuns de data e hora. Os métodos ParseExact e TryParseExact convertem uma representação em cadeia de caracteres que cumpra o padrão especificado por uma cadeia de caracteres de formato de data e hora. Para mais informações, consulte os artigos sobre cadeias de caracteres de formato de data e hora padrão e cadeias de caracteres de formato de data e hora personalizadas.

O objeto DateTimeFormatInfo atual fornece mais controle sobre como o texto deve ser interpretado como data e hora. As propriedades de um DateTimeFormatInfo descrevem os separadores de data e hora e os nomes de meses, dias e eras, bem como o formato das designações "AM" e "PM". O CultureInfo retornado por CultureInfo.CurrentCulture tem uma propriedade CultureInfo.DateTimeFormat que representa a cultura atual. Se você quer uma cultura específica ou configurações personalizadas, é necessário especificar o parâmetro IFormatProvider de um método de análise. Para o parâmetro IFormatProvider, especifique um objeto CultureInfo, o qual representa uma cultura ou um objeto DateTimeFormatInfo.

O texto que representa uma data ou hora pode ter algumas informações ausentes. Por exemplo, a maioria das pessoas supõe que a data "12 de março" representa o ano atual. Da mesma forma, "Março de 2018" representa o mês de março do ano 2018. O texto que representa a hora geralmente só inclui horas, minutos e uma designação de AM/PM. Os métodos de análise lidam com essas informações ausentes usando alguns padrões razoáveis:

  • Quando apenas a hora estiver presente, a parte de data usará a data atual.
  • Quando houver apenas uma data, a parte das horas será meia-noite.
  • Quando o ano não for especificado em uma data, o ano atual será usado.
  • Quando não é especificado o dia do mês, o primeiro dia do mês será usado.

Se a data estiver presente na cadeia de caracteres, ele deverá incluir o mês e, pelo menos, o dia ou o ano. Se a hora estiver presente, ela deverá incluir a hora e os minutos ou o designador AM/PM.

Você pode especificar a constante NoCurrentDateDefault para substituir esses padrões. Ao usar essa constante, as propriedades ausentes de ano, mês ou dia serão definidas com o valor 1. O último exemplo usando Parse demonstra esse comportamento.

Além de um componente de data e hora, a representação de cadeia de caracteres de data e hora pode incluir um deslocamento que indique a diferença de tempo em relação ao UTC (Tempo Universal Coordenado). Por exemplo, a cadeia de caracteres “2/14/2007 5:32:00 -7:00” define um horário sete horas antes do UTC. Se um deslocamento for omitido da representação de cadeia de caracteres de um horário, a análise retornará um DateTime do objeto com a propriedade Kind definida como DateTimeKind.Unspecified. Se for especificada uma diferença, a análise retorna um objeto DateTime com sua propriedade Kind definida como DateTimeKind.Local. Seu valor também é ajustado para o fuso horário local do computador. É possível modificar esse comportamento usando um valor DateTimeStyles com o método de análise.

O provedor de formato também é usado para interpretar uma data numérica ambígua. Não está claro quais componentes da data representada pela cadeia de caracteres "02/03/04" são mês, dia e ano. Os componentes são interpretados de acordo com a ordem dos formatos de data semelhantes no provedor de formato.

Analisar

O exemplo a seguir ilustra o uso do método DateTime.Parse para converter uma string em um DateTime. Este exemplo usa a cultura associada com o thread atual. Se CultureInfo associado à cultura atual não puder analisar a cadeia de caracteres de entrada, será gerado FormatException.

Dica

Todos os exemplos de C# neste artigo são executados no navegador. Pressione o botão Executar para ver a saída. Você também pode editá-los para experimentar como quiser.

Observação

Esses exemplos estão disponíveis no repositório de documentos do GitHub para C# e Visual Basic.

string dateInput = "Jan 1, 2009";
var parsedDate = DateTime.Parse(dateInput);
Console.WriteLine(parsedDate);
// Displays the following output on a system whose culture is en-US:
//       1/1/2009 00:00:00
Dim MyString As String = "Jan 1, 2009"
Dim MyDateTime As DateTime = DateTime.Parse(MyString)
Console.WriteLine(MyDateTime)
' Displays the following output on a system whose culture is en-US:
'       1/1/2009 00:00:00

É possível definir explicitamente a cultura cujas convenções de formatação serão usadas ao analisar uma cadeia de caracteres. Você especifica um dos objetos DateTimeFormatInfo padrão retornados pela propriedade CultureInfo.DateTimeFormat. O exemplo seguir usa um provedor de formato para analisar uma cadeia de caracteres em alemão em um DateTime. Ele cria um CultureInfo que representa a cultura de-DE. Esse objeto CultureInfo garante o sucesso da análise dessa cadeia de caracteres específica. Este processo impede que qualquer configuração esteja no CurrentCulture do CurrentThread.

var cultureInfo = new CultureInfo("de-DE");
string dateString = "12 Juni 2008";
var dateTime = DateTime.Parse(dateString, cultureInfo);
Console.WriteLine(dateTime);
// The example displays the following output:
//       6/12/2008 00:00:00
Dim MyCultureInfo As New CultureInfo("de-DE")
Dim MyString As String = "12 Juni 2008"
Dim MyDateTime As DateTime = DateTime.Parse(MyString, MyCultureInfo)
Console.WriteLine(MyDateTime)
' The example displays the following output:
'       6/12/2008 00:00:00

No entanto, você pode usar sobrecargas do método Parse para especificar provedores de formato personalizados. O método Parse não oferece suporte à análise de formatos não padrão. Para analisar data e hora expressadas em um formato não padrão, use o método ParseExact.

O exemplo a seguir usa a enumeração DateTimeStylespara especificar que as informações de data e hora atuais não devem ser adicionadas a DateTime nos campos não especificados.

var cultureInfo = new CultureInfo("de-DE");
string dateString = "12 Juni 2008";
var dateTime = DateTime.Parse(dateString, cultureInfo,
                                DateTimeStyles.NoCurrentDateDefault);
Console.WriteLine(dateTime);
// The example displays the following output if the current culture is en-US:
//      6/12/2008 00:00:00
Dim MyCultureInfo As New CultureInfo("de-DE")
Dim MyString As String = "12 Juni 2008"
Dim MyDateTime As DateTime = DateTime.Parse(MyString, MyCultureInfo,
                           DateTimeStyles.NoCurrentDateDefault)
Console.WriteLine(MyDateTime)
' The example displays the following output if the current culture is en-US:
'       6/12/2008 00:00:00

ParseExact

O método DateTime.ParseExact converte uma cadeia de caracteres em um objeto DateTime se ele estiver em conformidade com um dos padrões da cadeia de caracteres especificada. Quando uma cadeia de caracteres que não é de uma das formas especificadas é aprovada para esse método, é gerado FormatException. Você pode especificar um dos especificadores de formato de data e hora padrão ou uma combinação dos especificadores de formato personalizados. Usando os especificadores de formato personalizados, é possível construir uma cadeia de caracteres de reconhecimento personalizada. Para uma explicação dos especificadores, consulte os tópicos cadeias de caracteres de formato de data e hora padrão e cadeias de caracteres de formato de data e hora personalizadas.

No exemplo a seguir, o método DateTime.ParseExact recebe um objeto de cadeia de caracteres para analisar, seguido por um especificador de formato, seguido por um objeto CultureInfo. Esse método ParseExact só consegue analisar cadeias de caracteres que seguem o padrão de data por extenso na cultura en-US.

var cultureInfo = new CultureInfo("en-US");
string[] dateStrings = { " Friday, April 10, 2009", "Friday, April 10, 2009" };
foreach (string dateString in dateStrings)
{
    try
    {
        var dateTime = DateTime.ParseExact(dateString, "D", cultureInfo);
        Console.WriteLine(dateTime);
    }
    catch (FormatException)
    {
        Console.WriteLine("Unable to parse '{0}'", dateString);
    }
}
// The example displays the following output:
//       Unable to parse ' Friday, April 10, 2009'
//       4/10/2009 00:00:00
Dim MyCultureInfo As New CultureInfo("en-US")
Dim MyString() As String = {" Friday, April 10, 2009", "Friday, April 10, 2009"}
For Each dateString As String In MyString
    Try
        Dim MyDateTime As DateTime = DateTime.ParseExact(dateString, "D",
                                                     MyCultureInfo)
        Console.WriteLine(MyDateTime)
    Catch e As FormatException
        Console.WriteLine("Unable to parse '{0}'", dateString)
    End Try
Next
' The example displays the following output:
'       Unable to parse ' Friday, April 10, 2009'
'       4/10/2009 00:00:00

Cada sobrecarga dos métodos Parse e ParseExact também tem um parâmetro IFormatProvider que oferece informações específicas da cultura sobre a formatação da cadeia de caracteres. Esse objeto IFormatProvider é um objeto CultureInfo que representa uma cultura padrão ou um objeto DateTimeFormatInfo que retorna pela propriedade CultureInfo.DateTimeFormat. O ParseExact também usa uma cadeia de caracteres adicional ou um argumento de matriz de cadeia de caracteres que define um ou mais formatos de data e hora personalizados.

Confira também