]> git.ipfire.org Git - thirdparty/moment.git/commitdiff
Better checks for isValid in the parser #434 #409
authorTim Wood <washwithcare@gmail.com>
Wed, 12 Sep 2012 16:42:45 +0000 (09:42 -0700)
committerTim Wood <washwithcare@gmail.com>
Wed, 12 Sep 2012 16:42:45 +0000 (09:42 -0700)
moment.js
test/moment/is_valid.js

index 40cf3413d78d2c7e1361963717f1f5e06198d11b..05b5f912db2bb65ad1c494cb1e14216855f85df2 100644 (file)
--- a/moment.js
+++ b/moment.js
         }
         // 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;
 
     // 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
             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
             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);
             }
             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
             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
 
         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());
index 2e948b66692485056f528bc020f7d70ce14d654d..fe2278c3bd2fad1058322e074c1e7397a3874597 100644 (file)
@@ -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 = [