PDA

View Full Version : Fix for date rollover problem



adblockfreak
24 Aug 2010, 1:15 PM
Some users have reported a problem with ExtJS Date fields, where if something like "06-13-2001" is entered but the format is "dd-mm-yyyy", the date "rolls over" to "06-01-2002" when it is validated, rather than throwing an error. This is a limitation of the base ecmascript, not extjs, because this is what happens when you try to create a new Date object with those values.

I've finally found what I think is an elegant solution to this problem, and wanted to share, as well as solicit feedback.

I edited the Date.createParser function to check for rollover (all new lines are marked with "// added" comment):

...
var code = [
"Date.{0} = function(input){",
"var y, m, d, h = 0, i = 0, s = 0, ms = 0, o, z, u, v;",
"input = String(input);",
"d = new Date();",
"y = d.getFullYear();",
"m = d.getMonth();",
"d = d.getDate();",
"var results = input.match(Date.parseRegexes[{1}]);",
"if(results && results.length > 0){",
"{2}",
"if(u){",
"v = new Date(u * 1000);", // give top priority to UNIX time
"}else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0 && ms >= 0){",
"v = new Date(y, m, d, h, i, s, ms);",
"if(!dateMatches(v,y,m,d,h,i,s,ms)) {return null;}", // added
"}else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0){",
"v = new Date(y, m, d, h, i, s);",
"if(!dateMatches(v,y,m,d,h,i,s)) return null;", // added
"}else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0){",
"v = new Date(y, m, d, h, i);",
"if(!dateMatches(v,y,m,d,h,i)) return null;", // added
"}else if (y >= 0 && m >= 0 && d > 0 && h >= 0){",
"v = new Date(y, m, d, h);",
"if(!dateMatches(v,y,m,d,h)) return null;", // added
"}else if (y >= 0 && m >= 0 && d > 0){",
"v = new Date(y, m, d);",
"if(!dateMatches(v,y,m,d)) return null;", // added
"}else if (y >= 0 && m >= 0){",
"v = new Date(y, m);",
"if(!dateMatches(v,y,m)) return null;", // added
"}else if (y >= 0){",
"v = new Date(y);",
"if(!dateMatches(v,y)) return null;", // added
"}",
...


and then created the dateMatches function:

function dateMatches(dateObj, y, m, d, h, i, s, ms) {
if(y>=0 && y!=dateObj.getFullYear()) return false;
if(m>=0 && m!=dateObj.getMonth()) return false;
if(d>=0 && d!=dateObj.getDate()) return false;
if(h>=0 && h!=dateObj.getHours()) return false;
if(i>=0 && i!=dateObj.getMinutes()) return false;
if(s>=0 && s!=dateObj.getSeconds()) return false;
if(ms>=0 && ms!=dateObj.getMilliseconds()) return false;
return true;
}


Note: The year is converted to a 4-digit year before dateMatches() is ever called, so no need to worry about "99" vs. "1999" or anything like that.

FCTim
24 Aug 2010, 3:26 PM
There is a FR out there that I started from an override written by someone else.

http://www.sencha.com/forum/showthread.php?101797-DISCUSS-Ext.form.DateField-allowRollover

Also if you want all Dates to not rollover you can just use: Date.useStrict = true;

Hope that helps.