RegEx Date Validation for M/D/YYYY and MM/DD/YYYY (InfoPath) - regex

I'm looking for some RegEx for a custom pattern validation for a date field in InfoPath 2010. The accepted date format is m/d/yyyy or mm/dd/yyyy.
Attempt 1: (\d{1,2})/(\d{1,2})/(\d{4})
Attempt 2: (0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\d\d)
Had better luck with attempt 1, and not much at all with attempt 2.

I've been having some date and time validation issues with InfoPath 2010 and regex pattern matching can be a useful approach. A basic regex for validating m/d/yyyy (without catering for the specific days in a month and allowing for '0' prefix to month or day) would be something like the following (untested):
(0?[1-9]|1[012])\/(0?[1-9]|[12][0-9]|3[01])\/\d{4}
For something more sophisticated you could have a look at this SO answer.
However, in InfoPath the format of the date displayed can be completely different to the internal format and it is this internal format that your regex needs to match. If you drop a calculated field on your form and set it to the date field you want to validate you will see something like:
2013-05-08T12:13:14
So a regular expression (again ignoring specific days per month) required to validate the date component of this is:
\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])
But this won't match against the example date because it doesn't account for the time portion following the "T". So the trick is to use an expression to perform the match against the date substring only, e.g. in my case the following works:
not(xdUtil:Match(substring-before(dfs:dataFields/my:SharePointListItem_RW/my:DateCreated, "T"), "\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])"))

I tried the following and it worked:
\d{4}-\d{1,2}-\d{1,2}
As David pointed out the internal format might be different than the one displayed because when I tried \d\d/\d\d/\d\d\d\d it didn't work even though it caters to the displayed format of the date.

I had the same problem.
I used a rule on the date field to set another hidden text field to
string(datefield).
That always came out YYYY-MM-DD which is not too hard to create a regex against. I used this one.
((19|20)\d\d)-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])
Remember that it has to be an XML Regex which has some restrictions.
Then I set another rule on the hidden field to set a Boolean IsDateValid.

Related

grep first n lines only

I'm facing a problem greping the right date within a letter as a document.
Reason is to grep the date of document creation and not any further date within the text.
Usaly the dokument hold information about the company, my address, customer number, bill number....
and the date by when it was created.
Mayby a greeting and/or text maybe within dates again.
Often the date at begin of the document has different look as following.
December 1999 instead of 3.12.1999 as example.
If I grep the date in case of pattern
'(([0-9][0-9]{,1}\.)\s+('Januar'|'Februar'|'März'|'April'|'Mai'|'Juni'|'Juli'|'August'|'September'|'Oktober'|'November'|'Dezember')\s+([1-9][0-9][0-9][0-9]{1,}))'
sometimes get the wrong date as creation date. Reason is the different writing of dates in the documents.
Example 1 is what I usualy get and it works fine as I search for the date (creation date) with correct pattern.
Example 2 is in problem as I get a date, but it's NOT creation date which would be the 1st date. I get instead another date matching the pattern out from the text.
Example 1
Example 2
I could use different pattern '(([0-9][0-9]{,1}\.)([0-9][0-9]{,1}\.)([1-9][0-9][0-9][0-9]{1,}))' grepping the correct date in example 2 but then I would get same issue for example 1.
My idea was to search in first n lines only if pattern match take the date otherwise use different pattern.
I don't get the rule for pdfgrep using the first n lines only what would give me the possibility to use different pattern.
Has anybody an idea how to fix it?
Cheers, bdream
With GNU grep:
-m NUM: Stop reading a file after NUM matching lines.
Alternatively to GNU grep learn to use GNU gawk, specifically designed for such tasks.
Consider also learning python or GNU guile (then read SICP).

Regex for dates format

I am working under the Web Application based on ASP.NET MVC 5 and I have a great problem in my project with the field which gives the user the ability to choose format for showing Dates in the application.
The goal is to make RegularExpressionAttribute with the regex for validation date formats inputted by user.
Acceptable formats must be:
m/d/y,
m-d-y,
m:d:y,
d/m/y,
d-m-y,
d:m:y,
y/m/d,
y-m-d,
y:m:d
and the length of the date symbols may be as 'y' so far 'yyyy'. And they can be upper case.
So after hard-coding I've made the acceptable one:
((([mM]{1,4})([\/]{1})([dD]{1,4})([\/]{1})([yY]{1,4}))|(([mM]{1,4})([\-]{1})([dD]{1,4})([\-]{1})([yY]{1,4}))|(([mM]{1,4})([\:]{1})([dD]{1,4})([\:]{1})([yY]{1,4})))|((([dD]{1,4})([\/]{1})([mM]{1,4})([\/]{1})([yY]{1,4}))|(([dD]{1,4})([\-]{1})([mM]{1,4})([\-]{1})([yY]{1,4}))|(([dD]{1,4})([\:]{1})([mM]{1,4})([\:]{1})([yY]{1,4})))|((([yY]{1,4})([\/]{1})([mM]{1,4})([\/]{1})([dD]{1,4}))|(([yY]{1,4})([\-]{1})([mM]{1,4})([\-]{1})([dD]{1,4}))|(([yY]{1,4})([\:]{1})([mM]{1,4})([\:]{1})([dD]{1,4})))|((([yY]{1,4})([\/]{1})([dD]{1,4})([\/]{1})([mM]{1,4}))|(([yY]{1,4})([\-]{1})([dD]{1,4})([\-]{1})([mM]{1,4}))|(([yY]{1,4})([\:]{1})([dD]{1,4})([\:]{1})([mM]{1,4})))
This one works... But according to my scarce regex knowledge and experience I hope to get some help and better example for resolving this puzzle.
Thanks.
You have to generalize a bit.
m{1,4}([:/-])d{1,4}\1y{1,4}|d{1,4}([:/-])m{1,4}\2y{1,4}|y{1,4}([:/-])m{1,4}\3d{1,4}
Explanation:
instead of e.g. [mM] use m and set option for case insensitive match
([:/-]) all allowed delimiters as group
\1...\3 back reference to the delimiter group 1...3

date time of regular expression

I write a regular expression to determine the date time.(the assumption are every month has 31 days and the year only contain 1900 to 2099)
^(((((0?[1-9]|1[012])[- /.\\](0?[1-9]|[12][0-9]|3[01]))|((0?[1-9]|(1|2)[0-9]|3[01])[- /.\\](0?[1-9]|[1][012])))([- /.\\](19|20)\d{2})))$
the format of date time are:
dd-mm-yyyy
mm-dd-yyyy
0m-0d-yyyy
0d-0m-yyyy
m-d-yyyy
d-m-yyyy
everything works fine except one thing; if the date time like 32-10-2010, in my thought it should not be recognized, but in regex tester 2-10-2010 has been recognized. I wonder if there is any way to modify the regular expression to prevent it.
After removing the / at the end, your RegEx is working for me. Here's a simple Sublime Text RegEx Find/Replace:
Here is the adjusted regex:
^(((((0?[1-9]|1[012])[- /.\\](0?[1-9]|[12][0-9]|3[01]))|((0?[1-9]|(1|2)[0-9]|3[01])[- /.\\](0?[1-9]|[1][012])))([- /.\\](19|20)\d{2})))$
But a better solution would be to use the languages native date functionality. I can't think of a language that doesn't have inbuilt methods for these sorts of things.
For example, using JavaScript's Date object, or some such...
Try this one:
^((3[01]|0?[1-9]|[1-2][0-9])-(1[012]|0?[1-9])|((1[012]|0?[1-9])-(3[01]|0?[1-9]|[1-2][0-9])))-(19|20)[0-9][0-9]$
I've already given such an answer here.
This match one invalid date : 29-02-1900 but is correct for any date between 01-01-1900 and 31-12-2099
The valid date format pattern in your case is:
/^\d{1,2}-\d{1,2}-\d{4}$/
With RegEx you can validate only format of date, not a correct date, because it's a bad practice! Months can be with different days, so good luck to write pattern that will be consider it.
If You want to validate is date correct, use other build-in functions in your language. For example checkdate for PHP or etc.

Regex statements for date ranges <=4/1/2009 and <=10/01/2009

I need serious help building two Regex statements for a project. The software we're using ONLY accepts Regex for validation.
I need one that fires for any date <4/1/2009
and a second that fires for any date <10/1/2009
My co-worker gave me the following code to check for <=10/01/2010, but it checks leap years and all that stuff. I need something a little more streamlined than this in the MM/DD/YYYY format. Thanks in advance!
^(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:2[0-9][2-9][0-9])$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:201[1-9])$|^(?:(?:(?:0?[13578]|1[02])(\/|-|\.)31)|(?:(?:0?[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)))(\/|-|\.)(?:201[1-9])$|^(?:(?:(?:11)(\/|-|\.))(?:0?[1-9]|1\d|2[0-9]|30)(\/|-|\.))(2010)$|^(?:(?:(?:10|12)(\/|-|\.))(?:0?[1-9]|1\d|2[0-9]|30|31)(\/|-|\.))(2010)$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:2[0-9][2-9][0-9])$|^(?:(?:(?:0?[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0?[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)))(\/|-|\.)(?:2[0-9][2-9][0-9])$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:2011)$|^(?:0?2(\/|-|\.)29\3(?:(?:(?:2[0-9][1-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$
^(?:(?:0?2/(?:[12][0-9]|0?[1-9])|0?[13]/(?:3[01]|[12][0-9]|0?[1-9]))/2009|(?:0?2/(?:[12][0-9]|0?[1-9])|(?:0?[469]|11)/(?:30|[12][0-9]|0?[1-9])|(?:0?[13578]|1[02])/(?:3[01]|[12][0-9]|0?[1-9]))/(?:200[0-8]|19[0-9]{2}))$
will match any date between 1/1/1900 and 3/31/2009, ignoring leap years but otherwise matching only valid dates;
^(?:(?:0?2/(?:[12][0-9]|0?[1-9])|0?[469]/(?:30|[12][0-9]|0?[1-9])|0?[13578]/(?:3[01]|[12][0-9]|0?[1-9]))/2009|(?:0?2/(?:[12][0-9]|0?[1-9])|(?:0?[469]|11)/(?:30|[12][0-9]|0?[1-9])|(?:0?[13578]|1[02])/(?:3[01]|[12][0-9]|0?[1-9]))/(?:200[0-8]|19[0-9]{2}))$
does the same for 1/1/1900-9/30/2009.
EDIT: It looks like "firing" means "not matching" in your question. So
^(?:(?:(?:0?[469]|11)/(?:30|[12][0-9]|0?[1-9])|(?:0?[578]|1[02])/(?:3[01]|[12][0-9]|0?[1-9]))/2009|(?:0?2/(?:[12][0-9]|0?[1-9])|(?:0?[469]|11)/(?:30|[12][0-9]|0?[1-9])|(?:0?[13578]|1[02])/(?:3[01]|[12][0-9]|0?[1-9]))/(?:[3-9][0-9]{2}|2[1-9][0-9]|20[1-9])[0-9])$
will match any date from 4/1/2009 onwards, and
^(?:(?:11/(?:30|[12][0-9]|0?[1-9])|1[02]/(?:3[01]|[12][0-9]|0?[1-9]))/2009|(?:0?2/(?:[12][0-9]|0?[1-9])|(?:0?[469]|11)/(?:30|[12][0-9]|0?[1-9])|(?:0?[13578]|1[02])/(?:3[01]|[12][0-9]|0?[1-9]))/(?:[3-9][0-9]{2}|2[1-9][0-9]|20[1-9])[0-9])$
will match any date from 10/1/2009 onwards.
All regexes created using RegexMagic.

Better regex to validate date time

I have this regex (\d{4})-(\d{2})-(\d{2}) to detect a valid date, however, it is not perfect as some of the incoming data are 2009-24-09 (YYYY-DD-MM) and some are 2009-09-24 (YYYY-MM-DD).
Is it possible to have a one-line regex to detect whether the second & third portion is greater than 12 to better validate the date?
If you don't know the format, you will get ambiguous results.
take 2010-01-04 is that January 4th or March 1st?
You can't validate that with a regex.
As Albert said, try to parse the date, and make sure users know which format to use. You might try to separate the month and year portions into different fields or comboboxes.
Regex are not really good with dates validation, in my opinion is better to try to parse the date, and you could keep the regex as a sanity check before parsing it.
But if you still need it you can fix the month section using the following regex (\d{4})-(\d{2})-((1[012])|(0\d)|\d) but it goes downhill after that, since you need to check for correct days on months and leap years.
(\d{4})-((0[1-9]|1[0-2])-(\d{2}))|((\d{2})-(0[1-9]|1[0-2]))
YYYY-(MM-DD)|(DD-MM)
to validate YYYY-MM-DD or YYYY-DD-MM:
$ptn = '/(\d{4})-(?:(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-2])|(0[1-9]|' .
'[1-2][0-9]|3[0-2])-(0[1-9]|1[0-2]))/';
echo preg_match_all($ptn, '2009-24-09 2009-09-24 dd', $m); // returns 2
even so, the date could be invalid, e.g.: 2010-02-29, to deal with that there's checkdate():
checkdate(2, 29, 2010); // returns false