From: Iskren Chernev Date: Wed, 2 Oct 2013 07:18:04 +0000 (-0700) Subject: Simplified iso duration regex and removed overkill invalid checking logic X-Git-Tag: 2.3.0~10^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a061fb988015300aebb4cdfb12c704af357d16eb;p=thirdparty%2Fmoment.git Simplified iso duration regex and removed overkill invalid checking logic --- diff --git a/moment.js b/moment.js index 59a84673f..443070ea5 100644 --- a/moment.js +++ b/moment.js @@ -25,7 +25,8 @@ // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere - isoDurationRegex = /^(-)?(?:P)(?:(\d+(?:[,.]\d+)?)Y)?(?:(\d+(?:[,.]\d+)?)M)?(?:(\d+(?:[,.]\d+)?)W)?(?:(\d+(?:[,.]\d+)?)D)?(T(?:(\d+(?:[,.]\d+)?)H)?(?:(\d+(?:[,.]\d+)?)M)?(?:(\d+(?:[,.]\d+)?)S)?)?$/, + // isoDurationRegex = /^(-)?(?:P)(?:(\d+(?:[,.]\d+)?)Y)?(?:(\d+(?:[,.]\d+)?)M)?(?:(\d+(?:[,.]\d+)?)W)?(?:(\d+(?:[,.]\d+)?)D)?(T(?:(\d+(?:[,.]\d+)?)H)?(?:(\d+(?:[,.]\d+)?)M)?(?:(\d+(?:[,.]\d+)?)S)?)?$/, + 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, @@ -1079,30 +1080,24 @@ ms: ~~match[6] * sign }; } else if (!!(match = isoDurationRegex.exec(input))) { - timeEmpty = !(match[7] || match[8] || match[9]); - dateTimeEmpty = timeEmpty && !( - match[2] || match[3] || match[4] || match[5]); - - if (!(dateTimeEmpty || timeEmpty && match[6])) { - sign = (match[1] === "-") ? -1 : 1; - 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(',', '.')); - // apply sign while we're at it - return (isNaN(res) ? 0 : res) * sign; - }; - duration = { - y: parseIso(match[2]), - M: parseIso(match[3]), - w: parseIso(match[4]), - d: parseIso(match[5]), - h: parseIso(match[7]), - m: parseIso(match[8]), - s: parseIso(match[9]) - }; - } + sign = (match[1] === "-") ? -1 : 1; + 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(',', '.')); + // apply sign while we're at it + return (isNaN(res) ? 0 : res) * sign; + }; + duration = { + y: parseIso(match[2]), + M: parseIso(match[3]), + d: parseIso(match[4]), + h: parseIso(match[5]), + m: parseIso(match[6]), + s: parseIso(match[7]), + w: parseIso(match[8]), + }; } ret = new Duration(duration); diff --git a/test/moment/duration.js b/test/moment/duration.js index 19f420fe0..9b79a5bef 100644 --- a/test/moment/duration.js +++ b/test/moment/duration.js @@ -209,7 +209,7 @@ exports.duration = { test.equal(moment.duration("PT0,5S").asSeconds(), moment.duration({s: 0.5}).asSeconds(), "fractional seconds (comma)"); test.done(); }, - + "serialization to ISO 8601 duration strings" : function (test) { test.expect(6); test.equal(moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).toIsoString(), "P1Y2M3DT4H5M6S", "all fields"); @@ -220,7 +220,7 @@ exports.duration = { test.equal(moment.duration({}).toIsoString(), "P0D", "zero duration"); test.done(); }, - + "`isodate` (python) test cases" : function (test) { test.expect(24); test.equal(moment.duration("P18Y9M4DT11H9M8S").asSeconds(), moment.duration({y: 18, M: 9, d: 4, h: 11, m: 9, s: 8}).asSeconds(), "python isodate 1"); @@ -249,17 +249,16 @@ exports.duration = { test.equal(moment.duration("-P1DT2H3M4S").asSeconds(), moment.duration({d: -1, h: -2, m: -3, s: -4}).asSeconds(), "python isodate 24"); test.done(); }, - + "ISO 8601 misuse cases" : function (test) { - test.expect(9); + test.expect(8); test.equal(moment.duration("P").asSeconds(), 0, "lonely P"); test.equal(moment.duration("PT").asSeconds(), 0, "just P and T"); - test.equal(moment.duration("P1YT").asSeconds(), 0, "trailing T"); test.equal(moment.duration("P1H").asSeconds(), 0, "missing T"); test.equal(moment.duration("P1D1Y").asSeconds(), 0, "out of order"); - test.equal(moment.duration("PT.5S").asSeconds(), 0, "no leading zero for decimal"); - test.equal(moment.duration("PT1,S").asSeconds(), 0, "trailing decimal separator"); - test.equal(moment.duration("PT0,,5S").asSeconds(), 0, "extra decimal separator"); + test.equal(moment.duration("PT.5S").asSeconds(), 0.5, "accept no leading zero for decimal"); + test.equal(moment.duration("PT1,S").asSeconds(), 1, "accept trailing decimal separator"); + test.equal(moment.duration("PT1M0,,5S").asSeconds(), 60, "extra decimal separators are ignored as 0"); test.equal(moment.duration("P-1DS").asSeconds(), 0, "wrong position of negative"); test.done(); },