Como validar um DateTime em C #?


118

Duvido que eu seja o único que encontrou essa solução, mas se você tiver uma melhor, poste aqui. Eu simplesmente quero deixar esta questão aqui para que eu e outros possamos pesquisá-la mais tarde.

Eu precisava saber se uma data válida havia sido inserida em uma caixa de texto e este é o código que eu inventei. Eu disparo quando o foco sai da caixa de texto.

try
{
    DateTime.Parse(startDateTextBox.Text);
}
catch
{
    startDateTextBox.Text = DateTime.Today.ToShortDateString();
}

1
<sarcasm> julgando pelas respostas, acho que devo usar TryParse </sarcasm> Obrigado pelas ótimas respostas, pessoal. Eu nem havia pensado em TryParse
Matt

2
Um exemplo de uma pergunta fácil de google que se alguém perguntasse hoje seria injustamente fechada por não ter "pesquisas suficientes".
live-love

1
aqui está uma maneira fácil de fazer isso sem usar nenhuma função especial: < stackoverflow.com/questions/14917203/… >
Zameer

Parseusa até mesmo o TryParse
recurso de

2
Trabalhar com DateTimes é sempre uma dor de cabeça. Obrigado
Gonzo345

Respostas:


269
DateTime.TryParse

Acredito que isso seja mais rápido e significa que você não precisa usar o feio try / catches :)

por exemplo

DateTime temp;
if(DateTime.TryParse(startDateTextBox.Text, out temp))
{
  // Yay :)
}
else
{
  // Aww.. :(
}

2
Corrija-me se eu estiver errado, mas em C # (em oposição a, digamos, JavaScript) uma ramificação if / else requer chaves? Não me interpretando mal, não estou tentando examinar minuciosamente, é uma resposta fantástica e estou marcando-a com +1 porque me ajudou, mas pensei, já que você nunca sabe como serão os novos futuros usuários ao ver as respostas já postadas, isso poderia confundi-los. Claro, se você está tendo problemas com chaves em C #, essa questão seria a menor de suas preocupações ...
VoidKing

2
@VoidKing Você está correto sobre as chaves, mas se você tiver apenas 1 instrução naquele bloco, você não precisa usá-las. Isso se aplica a algumas outras linguagens também, mas posso ver como isso pode ser enganoso para os programadores mais recentes.
D.Galvez

2
@ D.Galvez Com licença, cheguei tarde à festa, mas é uma prática recomendada incluir os colchetes mesmo que haja apenas uma afirmação? Esta pode ser apenas uma situação em que a preferência pessoal é mais importante - e, nesse caso, acho que incluí- los é muito bom simplesmente para facilitar a leitura e consistência.
Nick,

2
Mal sabia eu, há 6 anos, que tal debate sobre colchetes ocorreria.
qui

É possível encurtar a inicialização da variável com if(DateTime.TryParse(startDateTextBox.Text, out var temp)):)
Alexandre Daubricourt

61

Não use exceções para controle de fluxo. Use DateTime.ExperimenteParse e DateTime.ExperimenteParseExact . Pessoalmente, prefiro TryParseExact com um formato específico, mas acho que há momentos em que TryParse é melhor. Exemplo de uso com base em seu código original:

DateTime value;
if (!DateTime.TryParse(startDateTextBox.Text, out value))
{
    startDateTextox.Text = DateTime.Today.ToShortDateString();
}

Razões para preferir esta abordagem:

  • Código mais claro (diz o que deseja fazer)
  • Melhor desempenho do que capturar e engolir exceções
  • Isso não captura exceções inadequadamente - por exemplo, OutOfMemoryException, ThreadInterruptedException. (Seu código atual poderia ser corrigido para evitar isso apenas capturando a exceção relevante, mas usar TryParse ainda seria melhor.)

24

Aqui está outra variação da solução que retorna verdadeiro se a string puder ser convertida em um DateTimetipo e falso caso contrário.

public static bool IsDateTime(string txtDate)
{
    DateTime tempDate;
    return DateTime.TryParse(txtDate, out tempDate);
}

3
Bem-vindo ao StackOverflow! Observe as respostas que já foram fornecidas, especialmente ao responder a uma pergunta com mais de três anos e que foi respondida com sucesso. Sua resposta já foi respondida por entrevistados anteriores.
Bob Kaufman



3

Um problema com o uso DateTime.TryParseé que ele não suporta o caso de uso de entrada de dados muito comum de datas inseridas sem separadores, por exemplo 011508.

Aqui está um exemplo de como apoiar isso. (Isso é de um framework que estou construindo, então sua assinatura é um pouco estranha, mas a lógica central deve ser utilizável):

    private static readonly Regex ShortDate = new Regex(@"^\d{6}$");
    private static readonly Regex LongDate = new Regex(@"^\d{8}$");

    public object Parse(object value, out string message)
    {
        msg = null;
        string s = value.ToString().Trim();
        if (s.Trim() == "")
        {
            return null;
        }
        else
        {
            if (ShortDate.Match(s).Success)
            {
                s = s.Substring(0, 2) + "/" + s.Substring(2, 2) + "/" + s.Substring(4, 2);
            }
            if (LongDate.Match(s).Success)
            {
                s = s.Substring(0, 2) + "/" + s.Substring(2, 2) + "/" + s.Substring(4, 4);
            }
            DateTime d = DateTime.MinValue;
            if (DateTime.TryParse(s, out d))
            {
                return d;
            }
            else
            {
                message = String.Format("\"{0}\" is not a valid date.", s);
                return null;
            }
        }

    }

Não estou preocupado com separadores no meu caso porque estou usando uma caixa de texto mascarada, mas posso ver como isso seria útil em outras situações que posso encontrar com este aplicativo.
Matt

Qual é a razão para usar a string DateTime sem separadores?
Sergei Kovalenko

1
    protected bool ValidateBirthday(String date)
    {
        DateTime Temp;

        if (DateTime.TryParse(date, out Temp) == true &&
      Temp.Hour == 0 &&
      Temp.Minute == 0 &&
      Temp.Second == 0 &&
      Temp.Millisecond == 0 &&
      Temp > DateTime.MinValue)
            return true;
        else
            return false;
    }

// suponha que a string de entrada tenha um formato de data curto.
por exemplo, "2013/7/5" retorna verdadeiro ou
"2013/2/31" retorna falso.
http://forums.asp.net/t/1250332.aspx/1
// bool booleanValue = ValidateBirthday ("12:55"); retorna falso


1
private void btnEnter_Click(object sender, EventArgs e)
{
    maskedTextBox1.Mask = "00/00/0000";
    maskedTextBox1.ValidatingType = typeof(System.DateTime);
    //if (!IsValidDOB(maskedTextBox1.Text)) 
    if (!ValidateBirthday(maskedTextBox1.Text))
        MessageBox.Show(" Not Valid");
    else
        MessageBox.Show("Valid");
}
// check date format dd/mm/yyyy. but not if year < 1 or > 2013.
public static bool IsValidDOB(string dob)
{ 
    DateTime temp;
    if (DateTime.TryParse(dob, out temp))
        return (true);
    else 
        return (false);
}
// checks date format dd/mm/yyyy and year > 1900!.
protected bool ValidateBirthday(String date)
{
    DateTime Temp;
    if (DateTime.TryParse(date, out Temp) == true &&
        Temp.Year > 1900 &&
       // Temp.Hour == 0 && Temp.Minute == 0 &&
        //Temp.Second == 0 && Temp.Millisecond == 0 &&
        Temp > DateTime.MinValue)
        return (true);
    else
        return (false);
}

1

Todas as respostas são muito boas, mas se você quiser usar uma única função, isso pode funcionar.

private bool validateTime(string dateInString)
{
    DateTime temp;
    if (DateTime.TryParse(dateInString, out temp))
    {
       return true;
    }
    return false;
}

1
Que tal retornar o resultado de DateTime.ExperimenteParse () em vez do bloco "if"? Além disso, seu IDE reclamaria sobre temp nunca usado, que você poderia declarar dentro da chamada de função diretamente como "out DateTime temp".
Sergei Kovalenko

0

Você também pode definir o DateTimeformato para umCultureInfo

public static bool IsDateTime(string tempDate)
{
    DateTime fromDateValue;
    var formats = new[] { "MM/dd/yyyy", "dd/MM/yyyy h:mm:ss", "MM/dd/yyyy hh:mm tt", "yyyy'-'MM'-'dd'T'HH':'mm':'ss" };
    return DateTime.TryParseExact(tempDate, formats, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out fromDateValue);
}

-1
protected static bool CheckDate(DateTime date)
{
    if(new DateTime() == date)      
        return false;       
    else        
        return true;        
} 

2
Embora este código possa resolver a questão, incluir uma explicação de como e por que isso resolve o problema realmente ajudaria a melhorar a qualidade de sua postagem e provavelmente resultaria em mais votos positivos. Lembre-se de que você está respondendo à pergunta para os leitores no futuro, não apenas para a pessoa que está perguntando agora. Por favor edite sua resposta para adicionar explicações e dar uma indicação do que limitações e premissas se aplicam.
Brian,

A questão é como validar um stringque pode ou não conter um DateTImevalor. Você está verificando se um dado DateTimetem valores padrão (correspondendo a 0001-01-01T00:00:00.0000000). Como isso responde à pergunta?
dbc

-3
DateTime temp;
try
{
    temp = Convert.ToDateTime(grd.Rows[e.RowIndex].Cells["dateg"].Value);
    grd.Rows[e.RowIndex].Cells["dateg"].Value = temp.ToString("yyyy/MM/dd");
}
catch 
{   
    MessageBox.Show("Sorry The date not valid", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop,MessageBoxDefaultButton.Button1,MessageBoxOptions .RightAlign);
    grd.Rows[e.RowIndex].Cells["dateg"].Value = null;
}

1
Você tem que verificar a validade por try catch. Então, você pode usar try catch para verificar todos os tipos de variáveis ​​e tornar válidas as funções globais e controlar tudo em seu projeto. Atenciosamente ..... Ashraf Khalifah
Ashraf Khalifah

-3
DateTime temp;
try
{
    temp = Convert.ToDateTime(date);
    date = temp.ToString("yyyy/MM/dd");
}
catch 
{
    MessageBox.Show("Sorry The date not valid", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop,MessageBoxDefaultButton.Button1,MessageBoxOptions .RightAlign);
    date = null;
}
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.