A sequência não foi reconhecida como um DateTime válido "formato dd / MM / aaaa"


172

Estou tentando converter meu valor formatado de seqüência de caracteres em tipo de data com formato dd/MM/yyyy.

this.Text="22/11/2009";

DateTime date = DateTime.Parse(this.Text);

Qual é o problema ? Ele tem uma segunda substituição que solicita IFormatProvider. O que é isso? Não eu preciso passar isso também? Se sim, como usá-lo neste caso?

Editar

Quais são as diferenças entre Parsee ParseExact?

Editar 2

Ambas as respostas de Slaks e Sam estão trabalhando para mim, atualmente o usuário está dando a entrada, mas isso será garantido por mim que elas são válidas usando maskTextbox.

Qual resposta é melhor, considerando todos os aspectos, como segurança do tipo, desempenho ou algo que você queira


7
@ Edit: É para isso que serve a documentação. msdn.microsoft.com/en-us/library/w2sa9yss.aspx
SLaks

2
ParseExact é para quando você conhece o formato exato da sequência de datas, o Parse é quando você deseja algo que possa lidar com algo um pouco mais dinâmico.
gingerbreadboy

Respostas:


255

Use DateTime.ParseExact.

this.Text="22/11/2009";

DateTime date = DateTime.ParseExact(this.Text, "dd/MM/yyyy", null);

8
Por que temos que passar nulo aqui?
Shantanu Gupta

3
A entrada pode ser "22/11/2009 12:00:00" ou "22/11/2009". Também a cultura da máquina de desenvolvimento pode ser diferente da cultura da produção. Então, o código acima funcionará perfeitamente?
Rahatur

8
@ Rahat, a análise exata não funcionará se o formato não corresponder. O padrão de formato acima é dd/MM/yyyypara que uma sequência de texto com um horário não seja analisada corretamente. Você precisará reduzir o tempo ou incluí-lo no padrão de formato. Há uma sobrecarga ParseExactque aceita uma matriz de padrões de formato e analisa o texto se ele corresponder a algum deles.
Samuel Neff

7
@SamuelNeff Por que você não usa, em CultureInfo.InvariantCulturevez do atual, se está definindo um formato?
Alvin Wong

3
@ Toolkit O motivo é que as barras na cadeia de formato não são barras literais. Eles são substituídos pela sequência separadora de datas na cultura atual. Portanto, depende da cultura da maneira como está escrita acima. Samuel Neff, tente Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");, isso quebrará sua solução. Para corrigir isso, use "dd'/'MM'/'yyyy"(protegendo as barras com aspas simples) ou @"dd\/MM\/yyyy"("escapando" das barras com barras invertidas).
Jeppe Stig Nielsen

44

Você precisa ligar ParseExact, que analisa uma data que corresponde exatamente ao formato fornecido por você.

Por exemplo:

DateTime date = DateTime.ParseExact(this.Text, "dd/MM/yyyy", CultureInfo.InvariantCulture);

O IFormatProviderparâmetro especifica a cultura a ser usada para analisar a data.
A menos que sua string venha do usuário, você deve passar CultureInfo.InvariantCulture.
Se a string vier do usuário, você deve passar CultureInfo.CurrentCulture, que usará as configurações especificadas pelo usuário em Opções Regionais no Painel de Controle.


2
@Slaks: CultureInfo.InvariantCulture não está disponível no código. Preciso usar algum namespace
Shantanu Gupta

3
using System.Globalization;
Slaks

2
Você também pode clicar com o botão direito do mouse no erro e clicar em resolver, isso colocará o namespace ausente para você.
Inkey

Você também pode clicar duas vezes o erro e ver uma seta para baixo, mostrando namespaces relacionados você pode usar
Usman Younas

Espaços também contam, por exemplo, se o seu formato da cadeia é "MM / dd / aaaa HH: mm: ss" (nota - 2 espaços) - então o seu formato para ParseExact também deve incluir os espaços
Chris Halcrow

20

A análise de uma representação de string de um DateTime é uma coisa complicada, porque diferentes culturas têm diferentes formatos de data. .Net está ciente desses formatos de data e os retira da sua cultura atual ( System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat) quando você liga DateTime.Parse(this.Text);

Por exemplo, a cadeia "22/11/2009" não corresponde ao ShortDatePattern dos Estados Unidos (en-US), mas corresponde à França (fr-FR).

Agora, você pode ligar DateTime.ParseExacte passar na seqüência de formato exata que você espera, ou em uma cultura apropriada DateTime.Parsepara analisar a data.

Por exemplo, isso analisará sua data corretamente:

DateTime.Parse( "22/11/2009", CultureInfo.CreateSpecificCulture("fr-FR") );

Obviamente, você não deve escolher aleatoriamente a França, mas algo apropriado às suas necessidades.

O que você precisa descobrir é o que System.Threading.Thread.CurrentThread.CurrentCultureestá definido e se / por que difere do que você espera.


sua solução não funciona para mim, ocorre um erro como "A string não foi reconhecida como um DateTime válido". e estou passando a seguinte data de entrada: "13/06/17" para a sua solução, mas ela fornece error.Plz me ajude.
Ghanshyam Lakhani 17/07/19

16

Embora as soluções acima sejam eficazes, você também pode modificar o arquivo webconfig com os seguintes ...

<configuration>
   <system.web>
     <globalization culture="en-GB"/>
   </system.web>
</configuration>

Ref: formato de data e hora diferente na máquina local em comparação com a máquina de produção


1
Amit Philips, você salvou o meu dia .. Eu tinha tentado todas as coisas possíveis. E essa pequena mudança funciona. Obrigado.
RNH

1
Amit, você é verdadeiramente o filho de Deus.
The Furious Urso


4

Depois de passar muito tempo, resolvi o problema

 string strDate = PreocessDate(data);
 string[] dateString = strDate.Split('/');
 DateTime enter_date = Convert.ToDateTime(dateString[1]+"/"+dateString[0]+"/"+dateString[2]);

3

use isso para converter string em datetime:

Datetime DT = DateTime.ParseExact(STRDATE,"dd/MM/yyyy",System.Globalization.CultureInfo.CurrentUICulture.DateTimeFormat)

3

Com base nessa referência , a próxima abordagem funcionou para mim:

// e.g. format = "dd/MM/yyyy", dateString = "10/07/2017" 
var formatInfo = new DateTimeFormatInfo()
{
     ShortDatePattern = format
};
date = Convert.ToDateTime(dateString, formatInfo);

2
private DateTime ConvertToDateTime(string strDateTime)
{
DateTime dtFinaldate; string sDateTime;
try { dtFinaldate = Convert.ToDateTime(strDateTime); }
catch (Exception e)
{
string[] sDate = strDateTime.Split('/');
sDateTime = sDate[1] + '/' + sDate[0] + '/' + sDate[2];
dtFinaldate = Convert.ToDateTime(sDateTime);
}
return dtFinaldate;
}

1

Assim como alguém acima disse que você pode enviá-lo como um parâmetro de string, mas ele deve ter este formato: '20130121', por exemplo, e você pode convertê-lo para esse formato, retirando-o diretamente do controle. Você poderá obtê-lo, por exemplo, em uma caixa de texto como:

date = datetextbox.text; // date is going to be something like: "2013-01-21 12:00:00am"

para convertê-lo em: '20130121' você usa:

date = date.Substring(6, 4) + date.Substring(3, 2) + date.Substring(0, 2);

para que o SQL possa convertê-lo e colocá-lo no seu banco de dados.


0

Você pode usar também

this.Text = "22112009";
DateTime newDateTime = new DateTime(Convert.ToInt32(this.Text.Substring(4, 4)), // Year
                                    Convert.ToInt32(this.Text.Substring(2,2)), // Month
                                    Convert.ToInt32(this.Text.Substring(0,2)));// Day

0

Trabalhou para mim abaixo do código:

DateTime date = DateTime.Parse(this.Text, CultureInfo.CreateSpecificCulture("fr-FR"));

Namespace

using System.Globalization;

-6

Alterar manualmente:

string s = date.Substring(3, 2) +"/" + date.Substring(0, 2) + "/" + date.Substring(6, 4);

A partir de 22/11/2015 será convertido em 22/11/2015

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.