Regular Expression | Leap Years and More

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))$

Regular expression visualization

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 like

Pattern.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



Leave a reply



Submit