]> git.ipfire.org Git - thirdparty/moment.git/commitdiff
Implement basic format and comma as ms separator in ISO 8601
authorIskren Chernev <iskren.chernev@gmail.com>
Tue, 29 Sep 2015 05:19:17 +0000 (22:19 -0700)
committerIskren Chernev <iskren.chernev@gmail.com>
Mon, 9 Nov 2015 02:27:40 +0000 (18:27 -0800)
src/lib/create/from-string.js
src/test/moment/create.js
src/test/moment/is_valid.js
src/test/qunit.js

index 4a7163b2d68859c6f08f835063274cc5a8769b6a..be30c8a113fe28dcbb7dc1dd6bf7090935cde816 100644 (file)
@@ -6,22 +6,32 @@ import getParsingFlags from './parsing-flags';
 
 // iso 8601 regex
 // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
-var isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
+var isoRegex = /^\s*((?:[+-]\d{6}|\d{4})-?(?:\d\d$|\d\d-?\d\d|W\d\d$|W\d\d-?\d|\d\d\d))(?:(T| )(\d\d(?::?\d\d(?::?\d\d(?::?[.,]\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
 
 var isoDates = [
-    ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
-    ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
-    ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
-    ['GGGG-[W]WW', /\d{4}-W\d{2}/],
-    ['YYYY-DDD', /\d{4}-\d{3}/]
+    ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/, true],
+    ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/, true],
+    ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/, true],
+    ['GGGG-[W]WW', /\d{4}-W\d{2}/, true],
+    ['YYYY-DDD', /\d{4}-\d{3}/, true],
+    ['YYYYYYMMDD', /[+-]\d{6}\d{2}\d{2}/, false],
+    ['YYYYMMDD', /\d{4}\d{2}\d{2}/, false],
+    // YYYYMM is NOT allowed by the standard
+    ['GGGG[W]WWE', /\d{4}W\d{2}\d/, false],
+    ['GGGG[W]WW', /\d{4}W\d{2}/, false],
+    ['YYYYDDD', /\d{4}\d{3}/, false]
 ];
 
 // iso time formats and regexes
 var isoTimes = [
-    ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/],
-    ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
-    ['HH:mm', /(T| )\d\d:\d\d/],
-    ['HH', /(T| )\d\d/]
+    ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/, true],
+    ['HH:mm:ss', /\d\d:\d\d:\d\d/, true],
+    ['HH:mm', /\d\d:\d\d/, true],
+    ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/, false],
+    ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/, false],
+    ['HHmmss', /\d\d\d\d\d\d/, false],
+    ['HHmm', /\d\d\d\d/, false],
+    ['HH', /\d\d/, null]
 ];
 
 var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
@@ -30,24 +40,36 @@ var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
 export function configFromISO(config) {
     var i, l,
         string = config._i,
-        match = isoRegex.exec(string);
+        match = isoRegex.exec(string),
+        extendedDate, extendedTime;
 
     if (match) {
         getParsingFlags(config).iso = true;
+
         for (i = 0, l = isoDates.length; i < l; i++) {
-            if (isoDates[i][1].exec(string)) {
+            if (isoDates[i][1].exec(match[1])) {
                 config._f = isoDates[i][0];
+                extendedDate = isoDates[i][2];
                 break;
             }
         }
         for (i = 0, l = isoTimes.length; i < l; i++) {
-            if (isoTimes[i][1].exec(string)) {
-                // match[6] should be 'T' or space
-                config._f += (match[6] || ' ') + isoTimes[i][0];
+            if (isoTimes[i][1].exec(match[3])) {
+                // match[2] should be 'T' or space
+                config._f += (match[2] || ' ') + isoTimes[i][0];
+                extendedTime = isoTimes[i][2];
                 break;
             }
         }
-        if (string.match(matchOffset)) {
+        if (extendedDate != null &&
+                extendedTime != null &&
+                extendedDate !== extendedTime) {
+            // extended and basic formats for date and time can NOT be mixed
+            config._isValid = false;
+            return;
+        }
+        matchOffset.lastIndex = 0;
+        if (matchOffset.exec(match[4])) {
             config._f += 'Z';
         }
         configFromStringAndFormat(config);
index 9afe7b67340029dcc623367fec6ac32cbd20445d..a3260c17376e2f7da720cf0601cdbd91c90e323b 100644 (file)
@@ -499,7 +499,82 @@ test('parsing iso', function (assert) {
         ['2011-281 18:04:20' + tz3,       '2011-10-08T18:04:20.000' + tz],
         ['2011-281 18:04:20.1' + tz2,     '2011-10-08T18:04:20.100' + tz],
         ['2011-281 18:04:20.11' + tz2,    '2011-10-08T18:04:20.110' + tz],
-        ['2011-281 18:04:20.111' + tz2,   '2011-10-08T18:04:20.111' + tz]
+        ['2011-281 18:04:20.111' + tz2,   '2011-10-08T18:04:20.111' + tz],
+        ['20111008T18',                   '2011-10-08T18:00:00.000' + tz],
+        ['20111008T1804',                 '2011-10-08T18:04:00.000' + tz],
+        ['20111008T180420',               '2011-10-08T18:04:20.000' + tz],
+        ['20111008T1804' + tz,            '2011-10-08T18:04:00.000' + tz],
+        ['20111008T180420' + tz,          '2011-10-08T18:04:20.000' + tz],
+        ['20111008T1804' + tz2,           '2011-10-08T18:04:00.000' + tz],
+        ['20111008T180420' + tz2,         '2011-10-08T18:04:20.000' + tz],
+        ['20111008T1804' + tz3,           '2011-10-08T18:04:00.000' + tz],
+        ['20111008T180420' + tz3,         '2011-10-08T18:04:20.000' + tz],
+        ['20111008T180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],
+        ['20111008T180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],
+        ['20111008T180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],
+        ['20111008 18',                   '2011-10-08T18:00:00.000' + tz],
+        ['20111008 1804',                 '2011-10-08T18:04:00.000' + tz],
+        ['20111008 180420',               '2011-10-08T18:04:20.000' + tz],
+        ['20111008 1804' + tz,            '2011-10-08T18:04:00.000' + tz],
+        ['20111008 180420' + tz,          '2011-10-08T18:04:20.000' + tz],
+        ['20111008 1804' + tz2,           '2011-10-08T18:04:00.000' + tz],
+        ['20111008 180420' + tz2,         '2011-10-08T18:04:20.000' + tz],
+        ['20111008 1804' + tz3,           '2011-10-08T18:04:00.000' + tz],
+        ['20111008 180420' + tz3,         '2011-10-08T18:04:20.000' + tz],
+        ['20111008 180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],
+        ['20111008 180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],
+        ['20111008 180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],
+        ['2011W40',                       '2011-10-03T00:00:00.000' + tz],
+        ['2011W406',                      '2011-10-08T00:00:00.000' + tz],
+        ['2011W406T18',                   '2011-10-08T18:00:00.000' + tz],
+        ['2011W406T1804',                 '2011-10-08T18:04:00.000' + tz],
+        ['2011W406T180420',               '2011-10-08T18:04:20.000' + tz],
+        ['2011W406 1804' + tz2,           '2011-10-08T18:04:00.000' + tz],
+        ['2011W406T1804' + tz,            '2011-10-08T18:04:00.000' + tz],
+        ['2011W406T180420' + tz,          '2011-10-08T18:04:20.000' + tz],
+        ['2011W406T1804' + tz2,           '2011-10-08T18:04:00.000' + tz],
+        ['2011W406T180420' + tz2,         '2011-10-08T18:04:20.000' + tz],
+        ['2011W406T1804' + tz3,           '2011-10-08T18:04:00.000' + tz],
+        ['2011W406T180420' + tz3,         '2011-10-08T18:04:20.000' + tz],
+        ['2011W406T180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],
+        ['2011W406T180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],
+        ['2011W406T180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],
+        ['2011W406 18',                   '2011-10-08T18:00:00.000' + tz],
+        ['2011W406 1804',                 '2011-10-08T18:04:00.000' + tz],
+        ['2011W406 180420',               '2011-10-08T18:04:20.000' + tz],
+        ['2011W406 1804' + tz,            '2011-10-08T18:04:00.000' + tz],
+        ['2011W406 180420' + tz,          '2011-10-08T18:04:20.000' + tz],
+        ['2011W406 180420' + tz2,         '2011-10-08T18:04:20.000' + tz],
+        ['2011W406 1804' + tz3,           '2011-10-08T18:04:00.000' + tz],
+        ['2011W406 180420' + tz3,         '2011-10-08T18:04:20.000' + tz],
+        ['2011W406 180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],
+        ['2011W406 180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],
+        ['2011W406 180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],
+        ['2011281',                       '2011-10-08T00:00:00.000' + tz],
+        ['2011281T18',                    '2011-10-08T18:00:00.000' + tz],
+        ['2011281T1804',                  '2011-10-08T18:04:00.000' + tz],
+        ['2011281T180420',                '2011-10-08T18:04:20.000' + tz],
+        ['2011281T1804' + tz,             '2011-10-08T18:04:00.000' + tz],
+        ['2011281T180420' + tz,           '2011-10-08T18:04:20.000' + tz],
+        ['2011281T1804' + tz2,            '2011-10-08T18:04:00.000' + tz],
+        ['2011281T180420' + tz2,          '2011-10-08T18:04:20.000' + tz],
+        ['2011281T1804' + tz3,            '2011-10-08T18:04:00.000' + tz],
+        ['2011281T180420' + tz3,          '2011-10-08T18:04:20.000' + tz],
+        ['2011281T180420,1' + tz2,        '2011-10-08T18:04:20.100' + tz],
+        ['2011281T180420,11' + tz2,       '2011-10-08T18:04:20.110' + tz],
+        ['2011281T180420,111' + tz2,      '2011-10-08T18:04:20.111' + tz],
+        ['2011281 18',                    '2011-10-08T18:00:00.000' + tz],
+        ['2011281 1804',                  '2011-10-08T18:04:00.000' + tz],
+        ['2011281 180420',                '2011-10-08T18:04:20.000' + tz],
+        ['2011281 1804' + tz,             '2011-10-08T18:04:00.000' + tz],
+        ['2011281 180420' + tz,           '2011-10-08T18:04:20.000' + tz],
+        ['2011281 1804' + tz2,            '2011-10-08T18:04:00.000' + tz],
+        ['2011281 180420' + tz2,          '2011-10-08T18:04:20.000' + tz],
+        ['2011281 1804' + tz3,            '2011-10-08T18:04:00.000' + tz],
+        ['2011281 180420' + tz3,          '2011-10-08T18:04:20.000' + tz],
+        ['2011281 180420,1' + tz2,        '2011-10-08T18:04:20.100' + tz],
+        ['2011281 180420,11' + tz2,       '2011-10-08T18:04:20.110' + tz],
+        ['2011281 180420,111' + tz2,      '2011-10-08T18:04:20.111' + tz]
     ], i;
     for (i = 0; i < formats.length; i++) {
         assert.equal(moment(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), formats[i][1], 'moment should be able to parse ISO ' + formats[i][0]);
index 2c1b13ea4ae3e442d4ed83c0dcc9f4b6ac3ed1cb..07999a0d9556da31353fb97a6c25bda0572ada76 100644 (file)
@@ -103,7 +103,8 @@ test('invalid string iso 8601 + timezone', function (assert) {
         '2010-01-40T24:01+00:00',
         '2010-01-40T23:60+00:00',
         '2010-01-40T23:59:60+00:00',
-        '2010-01-40T23:59:59.9999+00:00'
+        '2010-01-40T23:59:59.9999+00:00',
+        '2010-01-40T23:59:59,9999+00:00'
     ], i;
 
     for (i = 0; i < tests.length; i++) {
@@ -112,6 +113,26 @@ test('invalid string iso 8601 + timezone', function (assert) {
     }
 });
 
+test('valid string iso 8601 - not strict', function (assert) {
+    var tests = [
+        '2010-01-30 00:00:00,000Z',
+        '20100101',
+        '20100130',
+        '20100130T23+00:00',
+        '20100130T2359+0000',
+        '20100130T235959+0000',
+        '20100130T235959,999+0000',
+        '20100130T235959,999-0700',
+        '20100130T000000,000+0700',
+        '20100130 000000,000Z'
+    ];
+
+    for (var i = 0; i < tests.length; i++) {
+        assert.equal(moment(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');
+        assert.equal(moment.utc(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');
+    }
+});
+
 test('valid string iso 8601 + timezone', function (assert) {
     var tests = [
         '2010-01-01',
index 81a95e6fc7352a147f3703d451bddd078613f792..5a43df4616630c16a34d8fcaf2e87abdb6bdb56f 100644 (file)
@@ -8,8 +8,8 @@ export function module (name, lifecycle) {
     QUnit.module(name, {
         setup : function () {
             moment.locale('en');
-            moment.createFromInputFallback = function () {
-                throw new Error('input not handled by moment');
+            moment.createFromInputFallback = function (config) {
+                throw new Error('input not handled by moment: ' + config._i);
             };
             if (lifecycle && lifecycle.setup) {
                 lifecycle.setup();
@@ -27,8 +27,8 @@ export function localeModule (name, lifecycle) {
     QUnit.module('locale:' + name, {
         setup : function () {
             moment.locale(name);
-            moment.createFromInputFallback = function () {
-                throw new Error('input not handled by moment');
+            moment.createFromInputFallback = function (config) {
+                throw new Error('input not handled by moment: ' + config._i);
             };
             if (lifecycle && lifecycle.setup) {
                 lifecycle.setup();