Validate date textbox

19,689

Solution 1

The DateTime.TryParseExact(..) function does allow you to parse a date using a specific date format (for example, "mm/dd/yyyy"). However, if you want to be flexible on the number of digits in the year, then a regex might be a better choice.

Solution 2

You could try using regular expressions:

Regex dateRegExp = new Regex("^(((0?[1-9]|[12]\d|3[01])[\.\-\/](0?[13578]|1[02])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}|\d))|((0?[1-9]|[12]\d|30)[\.\-\/](0?[13456789]|1[012])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}|\d))|((0?[1-9]|1\d|2[0-8])[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}|\d))|(29[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00|[048])))$");

Match m = dateRegExp.Match(dateString);

if (m.Success) {
    //Valid Date'
}
else
{

    //No soup for you, 1 year'
}

(I "borrowed" the regexp from here: RegExpLib)

Share:
19,689
Sesame
Author by

Sesame

Updated on June 04, 2022

Comments

  • Sesame
    Sesame almost 2 years

    I'm using the following code to check if a valid date has been typed into a textbox:

    public bool ValidateDate(Control ctrl)
    {
        if (!string.IsNullOrEmpty(ctrl.Text))
        {
            DateTime value;
            if (!DateTime.TryParse(ctrl.Text, out value))
            {
                return false;
            }
        }
        return true;
    }
    
    
    private void txtStartDate_Validating(object sender, CancelEventArgs e)
    {
        if (Utils.ValidateDate(txtStartDate))
        {
            errorProvider.SetError(txtStartDate, "");
        }
        else
        {
            errorProvider.SetError(txtStartDate, "* Invalid Date");
            e.Cancel = true;
        }
    }
    

    This works fine for dates that are entered m/d/yy, m/d/yyyy, mm/dd/yy, mm/dd/yyyy. If a user enters in a date such as "11/17" this will evaluate to a valid date, but, unfortunately, I only want dates that have all three date parts.

    Is there an easy way to do this? I was thinking something a long the lines of checking if there are 2 "/" in the textbox, but I'm sure there is a cleaner way of achieving the desired result.

    EDIT: Thanks for all the suggestions everyone! I ended up using the following code which accepts M/d/yyyy and M/d/yy ~

        public bool ValidateDate(Control ctrl)
        {          
            if (!string.IsNullOrEmpty(ctrl.Text))
            {
                string[] formats = {"M/d/yyyy", "M/d/yy"};
                DateTime value;
    
                if  (!DateTime.TryParseExact(ctrl.Text, formats, new CultureInfo("en-US"), DateTimeStyles.None, out value))
                {
                    return false;
                }                
            }
            return true;
        }
    
  • t0mm13b
    t0mm13b over 14 years
    Don't forget, if you want to be flexible, whether to account for regional settings for DateTime, it could be dd/mm/yyyy (UK), mm/dd/yyyy (USA), or even yyyy/mm/dd, the slash separator could be different as well. Use the cultureinfo class to handle this..
  • Wil P
    Wil P over 14 years
    Nice. I totally forgot about TryParseExact. +1 from me.
  • Sesame
    Sesame over 14 years
    Normally, I would have... but, I am using Telerik's WinForms controls and I've just had too many problems with their MaskedEditBox. Thanks for the suggestion, any way.
  • Sesame
    Sesame over 14 years
    The DateTime.TryParseExact() has an override to accept multiple formats so I didn't have to give up the formatting flexibility. Thanks!
  • Neil
    Neil over 14 years
    Excellent. I had forgotten about that overload. I'm glad that worked for you.