Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Leap Year Regex 3

Status
Not open for further replies.

cgoodman

Programmer
Dec 29, 2008
7
I have written this leap year regex and checked it with the year 2099 and have gotten incorrect results. Here is my regex:

Code:
if((Year%4)==0 && (Year%100 != 0 || Year%400 == 0))
{
     ISLEAPYEAR = 1;
}

# Regular expression check, checks each month individually, due to differences in numbers of days/month. Also does leap year check for the possiblity of 02/29

if((ISLEAPYEAR == 1 && Date !~ "(0[13578]|1[02])(/)(0[1-9]|[12][0-9]|3[01])(/)(18|19|20)[0-9][0-9]" && Date !~ "(02)(/)(0[1-9]|[12][0-9])(/)(18|19|20)[0-9][0-9]" && Date !~ "(0[4689]|11)(/)(0[1-9]|[12][0-9]|30)(/)(18|19|20)[0-9][0-9]" && Date != "") || 
(ISLEAPYEAR == 0 && Date !~ "(0[13578]|10|12)(/)(0[1-9]|[12][0-9]|3[01])(/)(18|19|20)[0-9][0-9]" && Date !~ "(02)(/)(0[1-9]|1[0-9]|2[0-8])(/)(18|19|20)[0-9][0-9]" && Date !~ "(0[4689]|11)(/)(0[1-9]|[12][0-9]|30)(/)(18|19|20)[0-9][0-9]" && Date != ""))

Thanks for any help.
 
The regular expression is correct, simple mistake. thanks for checking it though.

No more help needed.
 
How would you do it feherke? Considering that you want to check for the presence of 0 prefixes too, I think regex may be a good choice, however I would probably do something like this to avoid checking the same thing multiple times:

Code:
        valid=0
        if(split(Date,d,"/") == 3) {
                if (d[3] ~ /(18|19|20)[0-9][0-9]/) {
                        if      (d[1] ~ /0[13578]|1[02]/ && d[2] ~ /0[1-9]|[12][0-9]|3[01]/) { valid=1 }
                        else if (d[1] ~ /0[4689]|11]/    && d[2] ~ /0[1-9]|[12][0-9]|30]/  ) { valid=1 }
                        else if (d[1] == "02") {
                                if      ( ISLEAPYEAR && d[2] ~ /0[1-9]|[12][0-9]/    ) { valid=1 }
                                else if (!ISLEAPYEAR && d[2] ~ /0[1-9]|1[0-9]|2[0-8]/) { valid=1 }
                        }
                }
        }

        print Date " is " ( valid ? "" :  "not " ) "a valid date"

Still a bit mess... but thats dates for you.

Annihilannic.
 
Anyway, I'd change this:
0[4689]|11
with this:
0[469]|11

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Hi

Annihilannic, I see nothing wrong in using regular expression to check the date's format. But not its content. While the dates are represented as sequences of numbers, so I would check the parts as numbers.

So I would do it like this :
Code:
function isvaliddate(d)
{
  if (d!~"^[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]$" || split(d,p,"/")!=3) return 0
  for (i in p) p[i]+=0
  e[1]=e[3]=e[5]=e[7]=e[8]=e[10]=e[12]=1
  if (p[3]<1800 || p[3]>2099 || p[1]<1 || p[1]>12 || p[2]<1 || p[2]>28+(p[1]!=2)*2+(p[1] in e)*2+(p[1]==2 && (p[3]%4==0 && (p[3]%100!=0 || p[3]%400==0)))) return 0
  return 1
}

Feherke.
 
Yep, that's neat. I'd make this slight adjustment to make it more readable:

Code:
function myisvaliddate(d)
{
        if (d!~"^[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]$" || split(d,p,"/")!=3) return 0
        e[1]=e[3]=e[5]=e[7]=e[8]=e[10]=e[12]=1
        [COLOR=blue]e[2]=p[3]%4==0 && (p[3]%100!=0 || p[3]%400==0) ? -1 : -2[/color]
        if (p[3]<1800 || p[3]>2099 || p[1]<1 || p[1]>12 || p[2]<1 || [COLOR=blue]p[2]>30+e[p[1]+0][/color]) return 0
        return 1
}

So continues the endless quest for the perfect code... :)

Annihilannic.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top