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


118

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

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

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

1
<sarcasm> судя по ответам, я думаю, мне следует использовать TryParse </sarcasm> Спасибо за отличные ответы, ребята. Я даже не думал о TryParse
Мэтт

2
Пример простого вопроса в Google, который, если бы кто-то задал сегодня, был бы несправедливо закрыт из-за «недостаточного количества исследований».
live-love

1
вот простой способ сделать это без использования каких-либо специальных функций: < stackoverflow.com/questions/14917203/… >
Zameer

даже Parseиспользует TryParse referencesource.microsoft.com/#mscorlib/system/globalization/...
Slai

2
Работа с DateTimes - всегда головная боль. Спасибо
Gonzo345

Ответы:


269
DateTime.TryParse

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

например

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

2
Поправьте меня, если я ошибаюсь, но в C # (в отличие, скажем, от JavaScript) разве ветвь if / else не требует фигурных скобок? Не поймите меня неправильно, я не пытаюсь тщательно исследовать, это фантастический ответ, и я ставлю ему +1, потому что он мне помог, но просто подумал, поскольку вы никогда не знаете, какие новые будущие пользователи при просмотре уже опубликованных ответов, это может сбить их с толку. Конечно, если у вас возникнут проблемы с фигурными скобками в C #, этот вопрос будет наименьшей из ваших проблем ...
VoidKing

2
@VoidKing Вы правы насчет фигурных скобок, но если у вас есть только 1 оператор в этом блоке, вам не нужно их использовать. Это применимо и к некоторым другим языкам, но я вижу, как это может ввести в заблуждение новых программистов.
D.Galvez

2
@ D.Galvez Извините, что я опоздал на вечеринку, но лучше ли включать скобки, даже если есть только одно утверждение? Это может быть просто ситуация, когда личные предпочтения наиболее важны - и в этом случае я считаю, что их включение довольно удобно просто для удобства чтения и согласованности.
Ник

2
6 лет назад я не знал, что могут возникнуть такие дебаты о скобках.
qui

Можно сократить инициализацию переменной с помощью if(DateTime.TryParse(startDateTextBox.Text, out var temp)):)
Alexandre Daubricourt

61

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

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

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

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

24

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

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

3
Добро пожаловать в StackOverflow! Пожалуйста, обратите внимание на уже предоставленные ответы, особенно при ответе на вопрос, которому больше трех лет и на который был успешно дан ответ. Ваш ответ уже был рассмотрен предыдущими респондентами.
Боб Кауфман



3

Проблема с использованием 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;
            }
        }

    }

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

В чем причина использования строки DateTime без разделителей?
Сергей Коваленко

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

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


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

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

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

1
Как насчет возврата результата DateTime.TryParse () вместо блока «if»? Кроме того, ваша IDE будет жаловаться на никогда не использовавшуюся временную температуру, которую вы можете объявить внутри вызова функции напрямую как «out DateTime temp».
Сергей Коваленко

0

Вы также можете определить 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);
}

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

2
Хотя этот код может решить вопрос, в том числе объяснение того, как и почему это решает проблему, действительно поможет улучшить качество вашего сообщения и, вероятно, приведет к большему количеству голосов за. Помните, что вы отвечаете на вопрос для будущих читателей, а не только для человека, который задает его сейчас. Пожалуйста , измените свой ответ , чтобы добавить объяснения и дать указание о том , что применять ограничения и допущения.
Брайан

Вопрос в том, как проверить, stringчто может содержать или не содержать DateTImeзначение. Вы проверяете, есть ли у заданного DateTimeзначения по умолчанию (соответствующие 0001-01-01T00:00:00.0000000). Как это отвечает на вопрос?
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
Вы должны проверить действительность, попробовав поймать. Таким образом, U может использовать try catch для проверки всех переменных типов и создания действительных глобальных функций и управления всем в вашем проекте. С наилучшими пожеланиями ..... Ашраф
Халифа

-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;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.