]> git.ipfire.org Git - thirdparty/moment.git/commitdiff
Added iso duration parsing #861
authorIskren Chernev <iskren.chernev@gmail.com>
Sun, 21 Jul 2013 08:29:30 +0000 (06:29 -0200)
committerIskren Chernev <iskren.chernev@gmail.com>
Sun, 21 Jul 2013 08:31:22 +0000 (06:31 -0200)
moment.js
test/moment/duration.js

index c18547cbfb4ee537812bba03de39c5e3f7d8c5db..ad5e74fc9fb25b0d4f9a0cc8cffded92a270cc81 100644 (file)
--- a/moment.js
+++ b/moment.js
@@ -22,6 +22,7 @@
         // ASP.NET json date format regex
         aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
         aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)\:(\d+)\.?(\d{3})?/,
+        isoDurationRegex = /^P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,
 
         // format tokens
         formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,
         var isDuration = moment.isDuration(input),
             isNumber = (typeof input === 'number'),
             duration = (isDuration ? input._input : (isNumber ? {} : input)),
-            matched = aspNetTimeSpanJsonRegex.exec(input),
+            // matching against regexp is expensive, do it on demand
+            aspMatched = null,
+            isoMatched = null,
             sign,
-            ret;
+            ret,
+            parseIso;
 
         if (isNumber) {
             if (key) {
             } else {
                 duration.milliseconds = input;
             }
-        } else if (matched) {
-            sign = (matched[1] === "-") ? -1 : 1;
+        } else if (!!(aspMatched = aspNetTimeSpanJsonRegex.exec(input))) {
+            sign = (aspMatched[1] === "-") ? -1 : 1;
             duration = {
                 y: 0,
-                d: ~~matched[2] * sign,
-                h: ~~matched[3] * sign,
-                m: ~~matched[4] * sign,
-                s: ~~matched[5] * sign,
-                ms: ~~matched[6] * sign
+                d: ~~aspMatched[2] * sign,
+                h: ~~aspMatched[3] * sign,
+                m: ~~aspMatched[4] * sign,
+                s: ~~aspMatched[5] * sign,
+                ms: ~~aspMatched[6] * sign
+            };
+        } else if (!!(isoMatched = isoDurationRegex.exec(input))) {
+            parseIso = function (inp) {
+                // We'd normally use ~~inp for this, but unfortunately it also
+                // converts floats to ints.
+                // inp may be undefined, so careful calling replace on it.
+                var res = inp && parseFloat(inp.replace(',', '.'));
+                return isNaN(res) ? 0 : res;
+            };
+            duration = {
+                y: parseIso(isoMatched[1]),
+                M: parseIso(isoMatched[2]),
+                d: parseIso(isoMatched[3]) + parseIso(isoMatched[7]) * 7,
+                h: parseIso(isoMatched[4]),
+                m: parseIso(isoMatched[5]),
+                s: parseIso(isoMatched[6]),
             };
         }
 
index 29feb9269ae8c3218d1c7310ef68ac99cb86c7d4..29cfbf55712afb24c9175d426540941f81732434 100644 (file)
@@ -198,6 +198,17 @@ exports.duration = {
         test.done();
     },
 
+    "instatiation from iso 8601 duration" : function (test) {
+        test.expect(6);
+        test.equal(moment.duration('P1Y2M3DT4H5M6S').asSeconds(), moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).asSeconds(), "all fields");
+        test.equal(moment.duration('P1W').asSeconds(), moment.duration({d: 7}).asSeconds(), "week field");
+        test.equal(moment.duration('P1M').asSeconds(), moment.duration({M: 1}).asSeconds(), "single month field");
+        test.equal(moment.duration('PT1M').asSeconds(), moment.duration({m: 1}).asSeconds(), "single minute field");
+        test.equal(moment.duration('P1MT2H').asSeconds(), moment.duration({M: 1, h: 2}).asSeconds(), "random fields missing");
+        test.equal(moment.duration('PY1MDT2HMS').asSeconds(), moment.duration({M: 1, h: 2}).asSeconds(), "random values missing");
+        test.done();
+    },
+
     "humanize" : function (test) {
         test.expect(32);
         moment.lang('en');