1

I am a new C# developer and I am using Regular Expression for my first time. As I am developing a validation class for my simple project, I am using Regex to develop a method validate the date entered by the user. The date should be of format MM/DD/YYYY only. I've developed the method but it gave me incorrect validation and I don't know why.

Here's the C# Regex method code:

public bool ValidateDate(string dateInput)
    {
        Regex datePattern = new Regex("^(1[0-2]|0[1-9])/(3[01]|[12][0-9]|0[1-9])/[0-9]{4}$"); 
        return !datePattern.IsMatch(dateInput);
    }

Then, since I have the following TextBox in ASP.NET:

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

Code-Behind:

protected void Button1_Click(object sender, EventArgs e)
    {
        Validator validator = new Validator();
        if (TextBox1.Text.ToString() != "")
        {
            if (validator.ValidateDate(TextBox1.Text.ToString()))
            {
                lblMessage.Text = "Correct";
            }
            else
            {
                lblMessage.Text = "Incorrect";
            }
        }
        else
        {
            lblMessage.Text = "Please enter a text";
        }
    }

When I tried to use the validation method with this textbox, it gave me incorrect result. For example, when I entered 11/10/2013, it gave me Incorrect. However, when I entered 2013/11/10, it gave me Correct and I don't know why

Would you kindly help me in fixing/modifying this validation method?

Technology Lover
  • 259
  • 1
  • 7
  • 19

3 Answers3

6

Use the dedicated DateTime.TryParseExact method for this purpose.

public bool ValidateDate(string dateInput)
{
    DateTime dt;
    return DateTime.TryParseExact(dateInput, "MM/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);
}
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • While definitely a pragmatic solution, I still wonder what's wrong with the actual regex. – David S. Nov 10 '13 at 20:13
  • I have a pathological hatred of methods with out parameters, but this code is certainly shorter than my - exception-based - solution. So +1 from me anyway. – David Arno Nov 10 '13 at 20:13
  • Thanks for your help. However, could you please tell me what will happen if I am passing a date of another format? What kind of error message I will get? – Technology Lover Nov 10 '13 at 20:14
  • 1
    @TechnologyLover If you pass in some other format this method will just return false and no exception will be thrown. Try it out. – Sriram Sakthivel Nov 10 '13 at 20:16
  • 1
    @TechnologyLover You don't get an error. `DateTime.TryParseExact` returns false and leaves dt null if it doesn't match. You may want to accept this answer, rather than mine, as it fits your needs and avoids exceptions. – David Arno Nov 10 '13 at 20:16
  • @DavidArno Just a correction `dt` won't be null. It will be unassigned. So default value would be `Datetime.MinValue`. Note that `DateTime` is not a class and it is a `struct` – Sriram Sakthivel Nov 10 '13 at 20:18
  • Guys, Thank you very much for your help and clear explanation. I really appreciate it. – Technology Lover Nov 10 '13 at 20:22
  • @SriramSakthivel if you don't mind, would you kindly check this question for me http://stackoverflow.com/questions/19891716/how-to-fix-this-regx-validation-method?noredirect=1#comment29592262_19891716 – Technology Lover Nov 10 '13 at 20:24
2

You do not need to use regex's for this. you can use the DateTime.ParseExact method.

So your method would be something like:

public bool ValidateDate(string dateInput)
{
    try 
    {
        DateTime.ParseExact(dateInput, "MM/dd/yyyy", CultureInfo.InvariantCulture);
        return true;
    }
    catch (FormatException) 
    {
        return false;
    }
}
David Arno
  • 42,717
  • 16
  • 86
  • 131
  • 2
    Exceptions are expensive – Sriram Sakthivel Nov 10 '13 at 20:02
  • @SriramSakthivel "If you ever get to the point where exceptions are significantly hurting your performance, you have problems in terms of your use of exceptions beyond just the performance" http://stackoverflow.com/a/891230/7122. Exceptions are a lot less expensive than you are suggesting. – David Arno Nov 10 '13 at 20:05
  • @DavidArno, thank you very much for your help. I really appreciate it. However, is there anyway to do it without using exceptions? Please help me if you have any suggestion. – Technology Lover Nov 10 '13 at 20:12
  • @TechnologyLover The way to use the DateTime class, without exceptions is covered by Sriram's answer. – David Arno Nov 10 '13 at 20:15
0

Not sure if this will work but try adding an '@' before "^(1[0-2]|0[1-9])/(3[01]|[12][0-9]|0[1-9])/[0-9]{4}$". I'm pretty sure that makes it a verbatim string literal so you can get away with not escaping characters that normally need to be escaped.

public bool ValidateDate(string dateInput)
{
    Regex datePattern = new Regex(@"^(1[0-2]|0[1-9])/(3[01]|[12][0-9]|0[1-9])/[0-9]{4}$"); 
    return !datePattern.IsMatch(dateInput);
}

More info: http://msdn.microsoft.com/en-us/library/aa691090(v=vs.71).aspx

Teeknow
  • 1,015
  • 2
  • 17
  • 39