Как проверить DateTime в С#?

Я сомневаюсь, что я единственный, кто придумал это решение, но если у вас есть лучшее решение, опубликуйте его здесь. Я просто хочу оставить этот вопрос здесь, чтобы я и другие могли найти его позже.

Мне нужно было указать, была ли введена действительная дата в текстовое поле, и это код, который я придумал. Я запускаю это, когда фокус покидает текстовое поле.

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

person Matt    schedule 16.12.2008    source источник
comment
‹сарказм›судя по ответам, я думаю, что мне следует использовать TryParse‹/сарказм› Спасибо за отличные ответы, ребята. Я даже не думал о TryParse   -  person Matt    schedule 16.12.2008
comment
Пример простого для Google вопроса, который, если бы кто-то задал его сегодня, был бы несправедливо закрыт из-за недостаточного исследования.   -  person live-love    schedule 28.06.2013
comment
вот простой способ сделать это без использования каких-либо специальных функций: ‹stackoverflow.com/questions/14917203/  -  person Zameer Ansari    schedule 11.09.2013
comment
даже Parse использует TryParse referencesource.microsoft.com/#mscorlib/system/ глобализация/   -  person Slai    schedule 01.02.2017
comment
Работа с DateTimes всегда неприятна. Спасибо   -  person Gonzo345    schedule 11.04.2017


Ответы (12)


DateTime.TryParse

Я считаю, что это быстрее, и это означает, что вам не нужно использовать уродливые попытки/уловы :)

e.g

DateTime temp;
if(DateTime.TryParse(startDateTextBox.Text, out temp))
{
  // Yay :)
}
else
{
  // Aww.. :(
}
person Chris James    schedule 16.12.2008
comment
Поправьте меня, если я ошибаюсь, но разве в C# (в отличие, скажем, от JavaScript) ветвь if/else не требует фигурных скобок? Не поймите меня неправильно, я не пытаюсь тщательно изучить, это фантастический ответ, и я добавляю его +1, потому что это помогло мне, но просто подумал, поскольку вы никогда не знаете, насколько новыми будут будущие пользователи при просмотре уже опубликованных ответов, это мог их запутать. Конечно, если у вас возникли проблемы с фигурными скобками в C#, этот вопрос будет наименьшим из ваших беспокойств... - person VoidKing; 12.12.2013
comment
@VoidKing Вы правы насчет фигурных скобок, но если у вас есть только 1 оператор в этом блоке, вам не нужно их использовать. Это применимо и к некоторым другим языкам, но я вижу, как это может ввести в заблуждение новых программистов. - person D.Galvez; 11.03.2014
comment
@ D.Galvez Извините за опоздание на вечеринку, но лучше ли включать скобки, даже если есть только одно утверждение? Это может быть просто ситуация, когда личные предпочтения являются наиболее важными, и в этом случае я считаю, что включение их достаточно просто для удобочитаемости и согласованности. - person Nick; 01.04.2014
comment
6 лет назад я и не подозревал, что возникнут такие дебаты о брекетах. - person Chris James; 03.04.2014
comment
Можно сократить инициализацию переменной с помощью if(DateTime.TryParse(startDateTextBox.Text, out var temp)) :) - person Alexandre Daubricourt; 04.12.2019
comment
Это короче: if (DateTime.TryParse(startDateTextBox.Text, out _)) - person AecorSoft; 19.12.2020

Не используйте исключения для управления потоком. Используйте DateTime.TryParse и DateTime.TryParseExact. Лично я предпочитаю TryParseExact с определенным форматом, но я думаю, что бывают случаи, когда TryParse лучше. Пример использования на основе исходного кода:

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

Причины предпочтения этого подхода:

  • Более четкий код (он говорит, что он хочет сделать)
  • Лучшая производительность, чем перехват и проглатывание исключений
  • Это не улавливает исключения ненадлежащим образом - например. OutOfMemoryException, ThreadInterruptedException. (Ваш текущий код можно исправить, чтобы избежать этого, просто перехватив соответствующее исключение, но использование TryParse все же будет лучше.)
person Jon Skeet    schedule 16.12.2008

Вот еще один вариант решения, который возвращает true, если строку можно преобразовать в тип DateTime, и false в противном случае.

public static bool IsDateTime(string txtDate)
{
    DateTime tempDate;
    return DateTime.TryParse(txtDate, out tempDate);
}
person Brendan Conrad    schedule 02.07.2012
comment
Добро пожаловать в StackOverflow! Пожалуйста, ознакомьтесь с ответами, которые уже были предоставлены, особенно при ответе на вопрос, которому более трех лет, и на который был успешно дан ответ. Ваш ответ уже обсуждался предыдущими респондентами. - person Bob Kaufman; 03.07.2012

Я бы использовал метод DateTime.TryParse(): http://msdn.microsoft.com/en-us/library/system.datetime.tryparse.aspx

person Alex Fort    schedule 16.12.2008

Как насчет использования TryParse?

person shapr    schedule 16.12.2008

Проблема с использованием DateTime.TryParse заключается в том, что он не поддерживает очень распространенный вариант использования ввода данных, когда даты вводятся без разделителей, например. 011508.

Вот пример того, как это поддержать. (Это из фреймворка, который я создаю, поэтому его подпись немного странная, но основная логика должна быть пригодна для использования):

    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;
            }
        }

    }
person Robert Rossney    schedule 16.12.2008
comment
Я не беспокоюсь о разделителях в моем случае, потому что я использую текстовое поле с маской, но я вижу, как это было бы удобно в других ситуациях, с которыми я могу столкнуться с этим приложением. - person Matt; 17.12.2008
comment
В чем причина использования строки DateTime без разделителей? - person Sergei Kovalenko; 09.08.2019

Один лайнер:

if (DateTime.TryParse(value, out _)) {//dostuff}
person AecorSoft    schedule 19.12.2020

    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;
    }

// предположим, что входная строка имеет короткий формат даты.
например. "2013/7/5" возвращает значение "истина",
"2013/2/31" возвращает значение "ложь".
http://forums.asp.net/t/1250332.aspx/1
//bool booleanValue = ValidateBirthday("12:55"); возвращает ложь

person Chung_TheWebDeveloper    schedule 05.07.2013

Все ответы довольно хороши, но если вы хотите использовать одну функцию, это может сработать. Он будет работать с другим форматом даты, но не будет работать с этой датой, например: 06.05.202, он будет считать ее действительной датой, но это не так.

private bool validateTime(string dateInString)
{
    DateTime temp;
    if (DateTime.TryParse(dateInString, out temp))
    {
       return true;
    }
    return false;
}
person Sayed Muhammad Idrees    schedule 26.02.2019
comment
Как насчет возврата результата DateTime.TryParse() вместо блока if? Кроме того, ваша IDE будет жаловаться на никогда не используемую временную переменную, которую вы можете объявить внутри вызова функции непосредственно как временную дату и время. - person Sergei Kovalenko; 09.08.2019

Вы также можете определить формат DateTime для определенного CultureInfo

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);
}
person Yanga    schedule 24.08.2019

person    schedule
comment
Вы должны проверить действительность, попробовав поймать. Таким образом, вы можете использовать try catch для проверки всех переменных типов и создания действительных глобальных функций и управления всем в вашем проекте. С наилучшими пожеланиями ..... Ашраф Халифа - person Ashraf Khalifah; 14.09.2016

person    schedule
comment
Хотя этот код может решить проблему, включая объяснение того, как и почему это решает проблему, действительно поможет улучшить качество. вашего сообщения и, вероятно, приведет к большему количеству голосов. Помните, что вы отвечаете на вопрос для будущих читателей, а не только для того, кто задает сейчас. Пожалуйста, отредактируйте свой ответ, чтобы добавить пояснения и указать, какие ограничения и предположения применяются. - person Brian; 10.04.2020
comment
Вопрос заключается в том, как проверить string, который может содержать или не содержать значение DateTIme. Вы проверяете, имеет ли данный DateTime значения по умолчанию (соответствующие 0001-01-01T00:00:00.0000000). Как это отвечает на вопрос? - person dbc; 10.04.2020