Analisar string para DateTime em c #

Eu tenho data e hora em uma string formatada como essa:

"2011-03-21 13:26" //year-month-day hour:minute 

Como posso analisá-lo para System.DateTime ?

Eu quero usar funções como DateTime.Parse() ou DateTime.ParseExact() se possível, para poder especificar o formato da data manualmente.

DateTime.Parse() tentará descobrir o formato da data especificada, e geralmente faz um bom trabalho. Se você pode garantir datas sempre estarão em um determinado formato, então você pode usar ParseExact() :

 string s = "2011-03-21 13:26"; DateTime dt = DateTime.ParseExact(s, "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture); 

(Mas observe que normalmente é mais seguro usar um dos methods TryParse no caso de uma data não estar no formato esperado)

Certifique-se de verificar Custom Data e Time Format Strings ao construir string de formato, especialmente prestar atenção ao número de letras e maiúsculas e minúsculas (ou seja, “MM” e “mm” significam coisas muito diferentes).

Outro recurso útil para seqüências de caracteres de formato C # é formatação de seqüência de caracteres em c #

Como estou explicando mais tarde, eu sempre TryParseExact methods TryParseExact e TryParseExact . Porque eles são um pouco volumosos para usar, eu escrevi um método de extensão que torna a análise muito mais fácil:

 var dtStr = "2011-03-21 13:26"; DateTime? dt = dtStr.toDate("yyyy-MM-dd HH:mm"); 

Ao contrário do Parse , ParseExact etc., ele não lança uma exceção e permite que você verifique via

if (dt.HasValue) { // continue processing } else { // do error handling }

se a conversão foi bem sucedida (neste caso, dt tem um valor que você pode acessar via dt.Value ) ou não (neste caso, é null ).

Isso permite até mesmo usar atalhos elegantes como o “Elvis” -operator ?. , por exemplo:

 int? year = dtStr?.toDate("yyyy-MM-dd HH:mm")?.Year; 

Aqui você também pode usar year.HasValue para verificar se a conversão foi bem-sucedida e, se não tiver êxito, o year conterá null , caso contrário, a parte do ano da data. Não há exceção lançada se a conversão falhou.

Experimente em .NetFiddle

 public static class Extensions { public static DateTime? toDate(this string dateTimeStr, string[] dateFmt) { // example: var dt = "2011-03-21 13:26".toDate(new string[]{"yyyy-MM-dd HH:mm", // "M/d/yyyy h:mm:ss tt"}); const DateTimeStyles style = DateTimeStyles.AllowWhiteSpaces; if (dateFmt == null) { var dateInfo = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat; dateFmt=dateInfo.GetAllDateTimePatterns(); } DateTime? result = null; DateTime dt; if (DateTime.TryParseExact(dateTimeStr, dateFmt, CultureInfo.InvariantCulture, style, out dt)) result = dt; return result; } public static DateTime? toDate(this string dateTimeStr, string dateFmt=null) { // example: var dt="2011-03-21 13:26".toDate("yyyy-MM-dd HH:mm"); // or simply var dt="2011-03-21 13:26".toDate(); // call overloaded function with string array param string[] dateFmtArr = dateFmt == null ? null : new string[] { dateFmt }; return toDate(dateTimeStr, dateFmtArr); } } 

Atualização: .toDate() (sem parâmetros) agora é padronizado para todos os padrões comuns de data / hora da cultura atual do encadeamento.
Observe que precisamos do result e do dt juntos, porque o TryParseExact não permite usar o DateTime? , que pretendemos devolver. No C # versão 7 você pode simplificar a function toDate seguinte maneira:

  // in C#7 only: "DateTime dt;" - no longer required, declare implicitly if (DateTime.TryParseExact(dateTimeStr, dateFmt, CultureInfo.InvariantCulture, style, out var dt)) result = dt; 

(Também seria permitido escrever out DateTime dt vez de out var dt .)

Exemplo:

 var dtStr="2011-03-21 13:26"; var dt=dtStr.toDate("yyyy-MM-dd HH:mm"); if (dt.HasValue) { Console.WriteLine("Successful!"); // ... dt.Value now contains the converted DateTime ... } else { Console.WriteLine("Invalid date format!"); } 

Como você pode ver, este exemplo apenas consulta dt.HasValue para ver se a conversão foi bem-sucedida ou não. Como um bônus extra, TryParseExact permite especificar DateTimeStyles estritos para que você saiba exatamente se uma string de data / hora apropriada foi passada ou não.


NB A function sobrecarregada permite que você passe uma matriz de formatos válidos usados ​​para análise / conversão de datas como mostrado aqui também (por exemplo, o TryParseExact suporta isso), por exemplo

 string[] dateFmt = {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt", "MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss", "M/d/yyyy hh:mm tt", "M/d/yyyy hh tt", "M/d/yyyy h:mm", "M/d/yyyy h:mm", "MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm"}; var dtStr="5/1/2009 6:32 PM"; var dt=dtStr.toDate(dateFmt); 

No entanto, para manter o código curto, estou usando apenas a sobrecarga da matriz de string TryParseExact, porque ele não funcionou com um parâmetro Generic.

Exemplo avançado:
Você pode usar o ?? operador padrão para um formato à prova de falhas, por

 var dtStr = "2017-12-30 11:37:00"; var dt = (dtStr.toDate()) ?? dtStr.toDate("yyyy-MM-dd HH:mm:ss"); 

Nesse caso, o .toDate() usaria formatos de data de cultura local comuns e, se todos eles falhassem, tentaria usar o formato padrão ISO "yyyy-MM-dd HH:mm:ss" como um substituto. Desta forma, a function de extensão permite “encadear” diferentes formatos de fallback facilmente.


Finalmente, aqui estão alguns comentários sobre o fundo (ou seja, a razão pela qual eu escrevi desta forma):

Eu estou preferindo TryParseExact neste método de extensão, porque você evita exception handling – você pode ler no artigo de Eric Lippert sobre exceções porque você deve usar TryParse em vez de Parse, eu cito-o sobre esse tópico: 2)

Esta decisão de projeto infeliz 1) [anotação: para deixar o método Parse lançar uma exceção] era tão irritante que, claro, a equipe de estruturas implementou TryParse logo em seguida, que faz a coisa certa.

Ele faz, mas TryParse e TryParseExact ambos ainda são muito menos do que confortável de usar: Eles forçam você a usar uma variável não inicializada como um parâmetro de out que não deve ser anulável e enquanto você está convertendo você precisa avaliar o valor de retorno booleano – ou você tem que usar uma instrução if imediatamente ou você tem que armazenar o valor de retorno em uma variável booleana adicional para que você possa fazer a verificação mais tarde. E você não pode simplesmente usar a variável de destino sem saber se a conversão foi bem-sucedida ou não.

Na maioria dos casos, você só quer saber se a conversão foi bem-sucedida ou não (e, claro, o valor foi bem-sucedido) , portanto, uma variável de destino anulável que mantém todas as informações seria desejável e muito mais elegante – porque toda a informação é apenas armazenado em um lugar: isso é consistente e fácil de usar, e muito menos propenso a erros.

O método de extensão que eu escrevi faz exatamente isso (ele também mostra o tipo de código que você teria que escrever toda vez se não for usá-lo).

Eu acredito que o benefício do .toDate(strDateFormat) é que ele parece simples e limpo – tão simples quanto o DateTime.Parse original deveria ser – mas com a capacidade de verificar se a conversão foi bem-sucedida e sem lançar exceções.


1) O que se entende aqui é que o tratamento de exceções (ou seja, um try { ... } catch(Exception ex) { ...} block) – que é necessário quando você está usando Parse porque ele lançará uma exceção se um inválido string é analisada – não é apenas desnecessária neste caso, mas também é irritante e complica seu código. TryParse evita tudo isso, pois o exemplo de código que forneci está sendo mostrado.


2) Eric Lippert é um conhecido colega da StackOverflow e trabalhou na Microsoft como desenvolvedor principal da equipe de compiladores C # por alguns anos.

 var dateStr = @"2011-03-21 13:26"; var dateTime = DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm", CultureInfo.CurrentCulture); 

Confira este link para outras strings de formato!

DateTime.Parse () deve funcionar bem para esse formato de seqüência de caracteres. Referência:

http://msdn.microsoft.com/pt-br/library/1k1skd40.aspx#Y1240

Está lançando um FormatException para você?

Coloque o valor de uma string legível em um DateTime .NET com código como este:

 DateTime.ParseExact("April 16, 2011 4:27 pm", "MMMM d, yyyy h:mm tt", null); 

Você também pode usar XmlConvert.ToDateString

 var dateStr = "2011-03-21 13:26"; var parsedDate = XmlConvert.ToDateTime(dateStr, "yyyy-MM-dd hh:mm"); 

É bom especificar o tipo de data, o código é:

 var anotherParsedDate = DateTime.ParseExact(dateStr, "yyyy-MM-dd hh:mm", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); 

Mais detalhes sobre diferentes opções de análise http://amir-shenodua.blogspot.ie/2017/06/datetime-parsing-in-net.html

A resposta simples e direta ->

 using System; namespace DemoApp.App { public class TestClassDate { public static DateTime GetDate(string string_date) { DateTime dateValue; if (DateTime.TryParse(string_date, out dateValue)) Console.WriteLine("Converted '{0}' to {1}.", string_date, dateValue); else Console.WriteLine("Unable to convert '{0}' to a date.", string_date); return dateValue; } public static void Main() { string inString = "05/01/2009 06:32:00"; GetDate(inString); } } } /** * Output: * Converted '05/01/2009 06:32:00' to 5/1/2009 6:32:00 AM. * */