Better regex to validate date time - regex

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

Related

Regex to match date of the week from date

Similar to How to use REGEX patterns to return day of the week if a date is entered? except I'm only looking for Regex answers not "any other clever method".
What is is simplest regex to match a particular day of the week, e.g. Thursday from a date string formatted like 2017-05-04T10:14:07Z.
This is what I have as a starting point.
2017-05-(04|11|18|25)T.*$
Is there a way to achieve a solution without too many pipes and covering all possible years or at least the last decade?
First and foremost, Thursday can not be extracted from a date string formatted like 2017-05-04T10:14:07Z, as "Thursday" never appears in the string. The best you can capture is the 2 digit day number (the "04").
You CAN get the day number (\d+-\d{1,2}-(\d{1,2})T.*?Z), However regex can't verify the correctness of the day. (for example, for a random year, can you tell me if Feb 28 is valid without listing every single instance?) So ONLY DO THIS IF YOU ACCEPT DAY MAY NOT BE VALID (or source will always be right)

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.

Validating text(input text is similar to date) in primefaces

I need an expression for the form yyyy-mm-dd(like date format), and I used regular expression : ^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$
But it only includes date till year 2099 but it is not the requirement, how to increase the upper limit to more ? Like 3000-01-01, 5000-01-01... etc
You need something like this:
^\d{4}[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$
I did not test it...
The problem lies with the "19|20" you see at the beginning. That's saying that the year must start with 19 or 20. You can generalize with by substituting (19|20) with \d\d which is to say any two digits are allowed. So the following:
^\d\d\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$
Whether this is acceptable or not is entirely up to you, though the more flexible you are with these sorts of things, the easier it is for a user to insert a value which they probably didn't mean to insert.
Also do keep in mind that there are other date formats used in the world. :)

regexes in calendar

I have a string in date format 06/09/2011 03:00 PM. I want to remove all of the forward slashes, and if the first digit of the month (06) is a zero, remove it as well as the first digit of the day (09) remove it as well. Any body who can help me out?
thanks!
The usual way to do this is by taking an available date parser where you hand in the input format and output it to a different output format.
Patterns differ, Implementations etc differ also. It is not convenient neither practicable to do date parsing via regex.
Something like that
0([1-9]+)/0([1-9]+)/([0-9]+)
Of course, it will only work in valid dates; it does not parse the date or anything.
BTW: I find better (more readable, detects errors in a more meaningful manner) fyr's answer. This is just to show that it can be done with regex, if fyr's solution is not available in your platform.

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.