From: Tim Wood Date: Wed, 12 Sep 2012 16:42:45 +0000 (-0700) Subject: Better checks for isValid in the parser #434 #409 X-Git-Tag: 1.7.1~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ba1a71e49f79e834ff8a9a49c1b6c2e12d1ed5e8;p=thirdparty%2Fmoment.git Better checks for isValid in the parser #434 #409 --- diff --git a/moment.js b/moment.js index 40cf3413d..05b5f912d 100644 --- a/moment.js +++ b/moment.js @@ -273,6 +273,10 @@ } // we store whether we used utc or not in the input array input[7] = forValid[7] = asUTC; + // if the parser flagged the input as invalid, we pass the value along + if (input[8] != null) { + forValid[8] = input[8]; + } // add the offsets to the time to be parsed so that we can have a clean array // for checking isValid input[3] += hoursOffset || 0; @@ -445,8 +449,8 @@ // function to convert string input to date function addTimeToArrayFromToken(token, input, datePartArray, config) { - var a; - //console.log('addTime', format, input); + var a, b; + switch (token) { // MONTH case 'M' : // fall through to MM @@ -458,9 +462,14 @@ for (a = 0; a < 12; a++) { if (getLangDefinition().monthsParse[a].test(input)) { datePartArray[1] = a; + b = true; break; } } + // if we didn't find a month name, mark the date as invalid. + if (!b) { + datePartArray[8] = false; + } break; // DAY OF MONTH case 'D' : // fall through to DDDD @@ -473,8 +482,7 @@ break; // YEAR case 'YY' : - input = ~~input; - datePartArray[0] = input + (input > 70 ? 1900 : 2000); + datePartArray[0] = ~~input + (~~input > 70 ? 1900 : 2000); break; case 'YYYY' : datePartArray[0] = ~~Math.abs(input); @@ -525,10 +533,19 @@ } break; } + + // if the input is null, the date is not valid + if (input == null) { + datePartArray[8] = false; + } } // date from string and format string function makeDateFromStringAndFormat(string, format) { + // This array is used to make a Date, either with `new Date` or `Date.UTC` + // We store some additional data on the array for validation + // datePartArray[7] is true if the Date was created with `Date.UTC` and false if created with `new Date` + // datePartArray[8] is false if the Date is invalid, and undefined if the validity is unknown. var datePartArray = [0, 0, 1, 0, 0, 0, 0], config = { tzh : 0, // timezone hour offset @@ -542,6 +559,8 @@ if (parsedInput) { string = string.slice(string.indexOf(parsedInput) + parsedInput.length); addTimeToArrayFromToken(tokens[i], parsedInput, datePartArray, config); + } else { + addTimeToArrayFromToken(tokens[i], null, datePartArray, config); } } // handle am pm @@ -857,6 +876,11 @@ isValid : function () { if (this._a) { + // if the parser finds that the input is invalid, it sets + // the eighth item in the input array to false. + if (this._a[8] != null) { + return !!this._a[8]; + } return !compareArrays(this._a, (this._a[7] ? moment.utc(this._a) : moment(this._a)).toArray()); } return !isNaN(this._d.getTime()); diff --git a/test/moment/is_valid.js b/test/moment/is_valid.js index 2e948b666..fe2278c3b 100644 --- a/test/moment/is_valid.js +++ b/test/moment/is_valid.js @@ -73,6 +73,25 @@ exports.is_valid = { test.done(); }, + "string nonsensical with format" : function (test) { + test.expect(2); + + test.equal(moment('fail', "MM-DD-YYYY").isValid(), false, 'string "fail" with format "MM-DD-YYYY"'); + test.equal(moment("xx-xx-2001", 'DD-MM-YYY').isValid(), false, 'string "xx-xx-2001" with format "MM-DD-YYYY"'); + test.done(); + }, + + "string with bad month name" : function (test) { + test.expect(2); + + moment.lang('en'); + + test.equal(moment('01-Nam-2012', 'DD-MMM-YYYY').isValid(), false, '"Nam" is an invalid month'); + test.equal(moment('01-Aug-2012', 'DD-MMM-YYYY').isValid(), true, '"Aug" is a valid month'); + + test.done(); + }, + "invalid string iso 8601" : function (test) { var tests = [