Regular Expression | Leap Years and More
As is mentioned elsewhere, regular expressions almost certanily not what you want. But, having said that, if you really want a regular expression, here is how it is built:
31 day months
(0[13578]|1[02])[\/.](0[1-9]|[12][0-9]|3[01])[\/.](18|19|20)[0-9]{2}
30 day months(0[469]|11)[\/.](0[1-9]|[12][0-9]|30)[\/.](18|19|20)[0-9]{2}
February 1-28 always valid(02)[\/.](0[1-9]|1[0-9]|2[0-8])[\/.](18|19|20)[0-9]{2}
February 29 also valid on leap years(02)[\/.]29[\/.](((18|19|20)(04|08|[2468][048]|[13579][26]))|2000)
which means it would be this if you put it all together:((0[13578]|1[02])[\/.](0[1-9]|[12][0-9]|3[01])[\/.](18|19|20)[0-9]{2})|((0[469]|11)[\/.](0[1-9]|[12][0-9]|30)[\/.](18|19|20)[0-9]{2})|((02)[\/.](0[1-9]|1[0-9]|2[0-8])[\/.](18|19|20)[0-9]{2})|((02)[\/.]29[\/.](((18|19|20)(04|08|[2468][048]|[13579][26]))|2000))
This version is a little shorter, but a little harder to understand.((0[13578]|1[02])[\/.]31[\/.](18|19|20)[0-9]{2})|((01|0[3-9]|1[1-2])[\/.](29|30)[\/.](18|19|20)[0-9]{2})|((0[1-9]|1[0-2])[\/.](0[1-9]|1[0-9]|2[0-8])[\/.](18|19|20)[0-9]{2})|((02)[\/.]29[\/.](((18|19|20)(04|08|[2468][048]|[13579][26]))|2000))
These scripts are long and unmaintainable. It should be clear that this isn't a good idea, but it is possible.Caveats:
- range 1800-2099 (more can be added without too much difficulty, but requires changes in 4-6 disparate places)
- requires 2 digit months and days (the strictness could be removed from the expression in ~8 places)
[\/.]
as seperators (8 places)- Hasn't been tested (we could check it against all digit combinations and compare with the javascript date function? [proof that we're reinventing the wheel])
Regex for d/m/yyyy with leap years
SAME INFO INSIDE EDIT SECTION IN FIRST POST
I've managed finally to edit my regex to match format I need. Here it is for next generations:
((((\b[1-9]\b|1[0-9]|2[0-8])[-]([1-9]|1[0-2]))|((29|30|31)[-]([13578]|1[02]))|((29|30)[-]([469]|11)))[-]([0-9][0-9][0-9][0-9]))|(29[-]2[-](([0-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)))
Working example: https://regex101.com/r/mjfoAH/3 Regular expression for ddmmyyyy date including validation for leap year
Dude, you asked the question I've been working on for a couple of weeks. I invite those commenting to give a date that breaks this. Now note that this works for the years 1000-9999, is Proleptic Gregorian and assumes that we won't change how leap-years work until the year 9999 ;)
^(?:(?:(?:0[1-9]|1\d|2[0-8])(?:0[1-9]|1[0-2])|(?:29|30)(?:0[13-9]|1[0-2])|31(?:0[13578]|1[02]))[1-9]\d{3}|2902(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00))$
Debuggex Demo
Java RegEx Date Validation - Leap Year
If m_datePattern
is a Pattern
, you're using compile
incorrectly. The signature of compile is
public static Pattern compile(String regex)
Since it's static
, it does not apply to an instance; it's normally called likePattern.compile(regex)
Using a Pattern
object instead of the class name makes no difference. Thus, if p
is a Pattern
object, then:p.compile(regex)
does the exact same thing as Pattern.compile(regex)
, even if p
is null
.The object is ignored.
Finally, compile
returns a Pattern
, which means the result has to be assigned to a Pattern
object:
pat = Pattern.compile(Regex);
Your code doesn't assign it anywhere. So the resulting pattern is just thrown away.Finally, when you use group(n)
, the groups, starting at 1, are the capture groups beginning with the first (
, second (
, etc., in the regex. Your regex is
"^((19|20)\\d\\d)-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])$"
In this regex, group(1)
is the year; group(2)
is 19 or 20; group(3)
is the month, and group(4)
is the day. Your code is using the wrong groups for the month and day. Either change the numbers, or designate (19|20)
as a non-capture group like this:"^((?:19|20)\\d\\d)-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])$"
Now it won't be counted as one of the capture groups.There may be other errors in your code. These are just the ones I noticed.
Regex to match ddmmyy with leap year as well?
Using regular expressions for this is madness, or at least borderline. But here is a sketch at a solution.
Days 00 through 28 should always be okay.
Day 30 should be okay if the month is not 02.
Day 31 should be okay if the month is not 02, 04, 06, 09, or 11.
Day 29 should be okay if the month is not 02 or the year is a leap year.
Since you only have two digits for the year, we assume you only want to operate in the current century. The leap years are the years which are divisible by 4. (There are some complications, but they do not apply in this century, because 2000 is evenly divisible by 400 as well as by 100.)
So we can enumerate the years which are leap years: 00, 04, 08, 12, 16, 20, ...
If the first digit in the two-digit year is an even number, then the year is a leap year if the second digit is 0, 4, or 8.
If the first digit is odd, the year is a leap year if the second digit is 2 or 6.
([01][0-9]|2[0-8])(0[0-9]|1[0-2])[0-9][0-9]|
30(0[013-9]|1[0-2])[0-9][0-9]|
31(0[13578]|1[02])[0-9][0-9]|
29((0[013-9]|1[0-2])[0-9][0-9]|02([0246][048]|[13579][26]))
Note that you will need a different regex for the years 1900-1999 because the leap years were different then (in particular, 1900 was not a leap year, because it is not divisible by 400.)
Related Topics
Localstorage Object Is Undefined in Ie
Check If Element Is Visible on Screen
Jquery Convert Line Breaks to Br (Nl2Br Equivalent)
Why Let and Var Bindings Behave Differently Using Settimeout Function
Why Duck Typing Is Allowed for Classes in Typescript
JavaScript .Replace Only Replaces First Match
Adding New Data to Firebase Users
Add Two Functions to Window.Onload
Cannot Set Property 'Innerhtml' of Null
How to Update a Specific Index from the Array in Firestore
Render Object Properties in React
Sort an Array by the "Levenshtein Distance" with Best Performance in JavaScript
Npm Start Error with Create-React-App
External Resource Not Being Loaded by Angularjs