Blog

Posts tagged with “javascript” and “as3”

The Ultimate Date Validation RegExp

Now, I'm not claiming to be a god at regular expressions, but I do own this shirt for a reason. That reason is that I like using RegExp to do a lot of heavy lifting for me. Case in point: validating a date format. It's one thing to pull out year, month and date, allowing for multiple delimiters; it's quite another to ensure that the actual values match expected results. Month values are only between 01 and 12. Days are not only between 01 and 31, but also exclude 29, 30, or 31 if the months aren't supposed to include them — including checking for leap years. I can do that. With Regular Expressions.

Here's how (for simplicty's sake, all years must start with 19xx or 20xx):

var yyyymmdd = /(?:((?:19|20)[0-9]{2})[\/\\\-. ]?(?:(0[1-9]|1[0-2])[\/\\\-. ]?([0-2][1-8]|[12]0|19)|(0[13-9]|1[0-2])[\/\\\-. ]?(29|30)|(0[13578]|1[02])[\/\\\-. ]?(31))|(19(?:[0][48]|[2468][048]|[13579][26])|20(?:[02468][048]|[13579][26]))[\/\\\-. ]?(02)[\/\\\-. ]?(29))/;
//if doing a replace: year is $1$8, month is $2$4$6$9, day is $3$5$7$10
var ddmmyyyy = /(?:(?:([0-2][1-8]|[12]0|19)[\/\\\-. ]?(0[1-9]|1[0-2])|(29|30)[\/\\\-. ]?(0[13-9]|1[0-2])|(31)[\/\\\-. ]?(0[13578]|1[02]))[\/\\\-. ]?((?:19|20)[0-9]{2})|(29)[\/\\\-. ]?(02)[\/\\\-. ]?(19(?:[0][48]|[2468][048]|[13579][26])|20(?:[02468][048]|[13579][26])))/;
//if doing a replace: year is $7$10, month is $2$4$6$9, day is $1$3$5$8
var mmddyyyy = /(?:(?:(0[1-9]|1[0-2])[\/\\\-. ]?([0-2][1-8]|[12]0|19)|(0[13-9]|1[0-2])[\/\\\-. ]?(29|30)|(0[13578]|1[02])[\/\\\-. ]?(31))[\/\\\-. ]?((?:19|20)[0-9]{2})|(02)[\/\\\-. ]?(29)[\/\\\-. ]?(19(?:[0][48]|[2468][048]|[13579][26])|20(?:[02468][048]|[13579][26])))/;
//if doing a replace: year is $7$10, month is $1$3$5$8, day is $2$4$6$9

I'll break down the first example.
The entire expression looks for most likely values first, then looks for less likely, yet still valid values.

  • First it looks for a year with
    • a month value is between 01-12 and the day value is between 01-28.
    • If not, it checks if the month value is 01, or 03-12 and the day is either 29 or 30.
    • Failing that, it checks if the month is one of 01,03,05,07,08,10, or 12 and the day is 31.
  • Failing that, it does one last sanity check to see if the year was a leap year (only checking the years starting with 19xx or 20xx, so values are actually easily calculatable) and the date is 02-29.

If all of that fails, it isn't a valid date.

Tags: , , , ,
2012.06.07 10:23 AM | Permalink 0 Comments

Quick date validation with a Regular Expression

/(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:29|30))|(?:(?:0[13578]|1[02])-31))/

Here's the breakdown of what it does:

Given a date format of YYYY-MM-DD (standard MySQL date format and easiest format for sorting) it makes sure that

  1. the year is numeric and starts with 20 or 19, and
  2. the month is numeric and is either
    1. between 01 - 12 and followed by a numeric day value between 01-28;
    2. between 01 - 12 but not 02 and followed by a day value of 29 or 30; or
    3. one of 01,03,05,07,08,10,12 and followed by a day value of 31

I have left out Feb. 29th so that you are forced to do a secondary leap year check.

Tags: , , ,
2010.01.28 11:43 AM | Permalink 0 Comments

Difference between using Object as associative array in Flash AS3 and JavaScript

As I was porting a Roman number converter (I will post it shortly) I had written in JavaScript to AS3 and ran into an interesting "quirk" of the AS3 Object class. I doesn't keep the keys in the same order that they were declared. The code used an Object literal as an associative array; holding each roman "digit" along with it's decimal equivalent in descending order by value. I'd then use a for ... in loop to cycle through the object. In JavaScript I'd get the values in the same order they had been generated. AS3 seems to be a little more cavalier. The following code in Javascript:

var o = {
"name1":1,
"name2":1,
"name3":1,
"name4":1,
"name5":1
};
var a=0;
for (var n in o) {
document.write(" o " + a + ":"+n);
a++;
}

produces this result in all major browsers (Firefox 3.5, IE 8, Safari 4, Opera 9.54, Chrome 2):
o 0:name1 o 1:name2
o 2:name3
o 3:name4
o 4:name5

However, using the following code in the Flash IDE

var o:Object = {
"name1":1,
"name2":1,
"name3":1,
"name4":1,
"name5":1
};
var a:uint = 0
for (var n:String in o) {
trace(" o " + a + ":"+n);
a++;
}

resulted in the following trace result:
o 0:name4
o 1:name5
o 2:name1
o 3:name2
o 4:name3

Oddly, it seemed to produce the exact same order each time I ran it. I tried it with a Dictionary, to see if the made a difference, but results were similar. I tried different values, to try and find a reason for the ordering -- to no avail. If someone knows why it's consistently picks the same random order, I'd love to know.

Tags: , , ,
2009.08.16 11:25 PM | Permalink 0 Comments