Thursday, June 14, 2012

Regular Expressions for Date/Time Validation

On one of my projects I was asked to validate the date/time input into a textbox. So my solution was to use the built in Validator controls in VS2008. Since this project is based on 2008 I will use that for the IDE on this project.

The first step for this project was to select the RegularExpressionValidator from the toolbox under Validation tab. Once I dragged it to the project all I had to do was add the ControlToValidate, some text on error and then add the ValidationExpression. This is where it got a little tricky as I assumed all I had to do was find someone that already had a sample that worked and add it. Here is a link that has some good examples on validation.Self-Validating-Text-Box




The problem was for the examples I found none of them seamed to work correctly. So then I had to dive into Regular Expressions and try to figure out how to make the one I downloaded work.

Here is a link on using regular expressions:The-30-Minute-Regex-Tutorial. After reading this I then downloaded Expresso and installed it on my computer. From here I could then use Expresso to test and validate my expressions.

Here is the expression I found on the internet:

\A(?:1[0-2]|0[1-9])[/.-](?:3[01]|[12][0-9]|0[1-9])[/.-][0-9]{4}[ \t]+(?:1[0-2]|0[1-9])[:.](?:1[0-9]|0[1-9])[:.][0-5][0-9][ \t]+(?:AM|PM)

This seamed to work fine on my first test case, so I put it in my code and of course it did not work. Therefore I then put it into the Expresso tool and started to run test cases.


  

So with a date/time of 06/13/2012 02:11:10 AM it worked fine, but when I changed the date/time to 06/13/2012 02:31:10 AM it did not work. So from here I needed to dive into regular expressions to see why it was not working. The first step I took was to review the Regex Analyzer on the right screen of Espresso. This will explain what the commands are doing and as listed below I went thru each on of them.
 
\A - Beginning of string
 Date
(?:1[0-2]|0[1-9]) 
  • () - grouping
  • ?:  match : 0 or 1 times
  • 1[ looking for 1
  • [0-2] range of 0 to 2
  • 0[ looking for 0
       This will match the month forcing it to be 1 to 12

[/.-] - Match [] operator so this will match / . -

        This will match the /

(?:3[01]|[12][0-9]|0[1-9])
  • () - grouping
  • ?:  match : 0 or 1 times
  • 3[ looking for 3
  • [01] - match 01
  • [12] match 12
  • [0-9] range of 0 to 9
  • 0[ looking for 0
  • [1-9] range of 1 to 9
       This will match the day forcing it to be 0 to 31

[/.-]  Match [] operator so this will match / . -

       This will match the /

[0-9]{4} - any class from 0-9 repeat 4 times

     This will match the year to 2012

[ \t]+ match \t tab with any repetitions

     This will match any tabs

Time

(?:1[0-2]|0[1-9])
  • () - grouping
  • ?:  match : 0 or 1 times
  • 1[ looking for 1
  • [0-2] range of 0 to 2
  • 0[ looking for 0
  • [1-9] range of 1 to 9
        This will match 1 and force it to 0 to 2 and 0 to 1 to 9. Which will work for the first test case but not anthing greater then 1.

[:.] - any character in this class


(?:1[0-9]|0[1-9])

  • () - grouping
  • ?:  match : 0 or 1 times
  • 1[ looking for 1
  • [0-9] range of 0 to 9
  • 0[ looking for 0
  • [1-9] range of 1 to 9
        This will match only 1 from 0 to 9 and 0 from 1 to 9. 

[:.]- any character in this class


[0-5][0-9]
  • [0-5] - match 0 to 5
  • [0-9] - match 0 to 9
       This will match the data to the range 00 to 59

[ \t]+ match \t tab with any repetitions
     This will match any tabs

(?:AM|PM) - Match AM or PM
      This will get the AM or PM

So from this break down I can see a couple of my problems in the time.

  1. (?:1[0-2]|0[1-9]) I need this to go from 0 to 5
  2. (?:1[0-9]|0[1-9]) I need this to also go from 0 to 5
  3. [ \t]+  I need to also handle space
  4. [/.-]  I only want to match /
Below I have listed my new changes. I ran thru testing on expression and it appears to work. Hopefully this will help some else out on implementing this functionaly.
\A(?:1[0-2]|0[1-9])[/](?:3[01]|[12][0-9]|0[1-9])[/][0-9]{4}[ \s]+(?:1[0-2]|0[1-9])[:.](?:[1-5][0-9]|0[1-9])[:.][0-5][0-9][ \s]+(?:AM|PM)




 Also you can easily use regex in CSharp to validate or filter data just like grep. All you need to do is add using System.Text.RegularExpression and then call RegEx.IsMatch(...) to evaluate the data of interest.

1 comment:

  1. This is an excellent write up. I am glad to finally see that Microsoft is entering the *nix revolution!

    ReplyDelete