Як перевірити дату часу в 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 referenceource.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 #, це питання
викликає

2
@VoidKing Ви маєте рацію щодо фігурних брекетів, але якщо у вас є лише 1 твердження в цьому блоці, вам не потрібно їх використовувати. Це стосується і деяких інших мов, але я бачу, як це може ввести в оману новітні кодери.
D.Galvez

2
@ D.Galvez Вибачте, що я пізно прийшов на вечірку, але чи є найкращою практикою включати дужки, навіть якщо є лише 1 заява? Це може бути просто ситуація, коли особисті переваги є найважливішими - і в такому випадку я вважаю, що включення їх є досить приємним просто для читабельності та послідовності.
Нік

2
Мало я знав 6 років тому, що відбуватиметься така дискусія щодо дужок.
qui

Можна скоротити ініціалізацію змінної за допомогою if(DateTime.TryParse(startDateTextBox.Text, out var temp)):)
Олександр Даубрікорт

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" повертає значення true або
"2013/2/31" повертає значення false.
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 () замість блоку "якщо"? Крім того, ваш IDE буде скаржитися на ніколи не використовуваний темп, який ви можете оголосити всередині виклику функції безпосередньо як "поза тимчасової температури".
Сергій Коваленко

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
Ви повинні перевірити дійсність, якщо спробувати ловити. Таким чином, ви можете використовувати спробувати 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.