From: Isaac Cambron Date: Wed, 2 Oct 2013 22:25:52 +0000 (-0400) Subject: fixes for review X-Git-Tag: 2.3.0~7^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fb913bf141ffd3532e33c5c028d6aa47076f5e40;p=thirdparty%2Fmoment.git fixes for review --- diff --git a/moment.js b/moment.js index 18863fe7b..91865c193 100644 --- a/moment.js +++ b/moment.js @@ -476,17 +476,22 @@ } function checkOverflow(m) { + var overflow; if (m._a && m._pf.overflow === -2) { - m._pf.overflow = + overflow = m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH : - m._a[DATE] < 1 || m._a[DATE] > - (m._pf.overflowMonthOk ? (isLeapYear(m._a[YEAR]) ? 364 : 365) : daysInMonth(m._a[YEAR], m._a[MONTH])) ? DATE : + m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE : m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR : m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE : m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND : m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND : -1; + if (m._pf._overflowDayOfYear && (overflow < 0 || overflow > 2)) { + overflow = 2; + } + + m._pf.overflow = overflow; } } @@ -495,12 +500,11 @@ empty : false, unusedTokens : [], unusedInput : [], - overflowMonthOk : false, overflow : -2, charsLeftOver : 0, nullInput : false, invalidMonth : null, - userInvalidated : false + userInvalidated : false, }; } @@ -911,9 +915,7 @@ case 'DDD' : // fall through to DDDD case 'DDDD' : if (input != null) { - datePartArray[MONTH] = 0; - datePartArray[DATE] = toInt(input); - config._pf.overflowMonthOk = true; + config._dayOfYear = toInt(input); } break; @@ -970,19 +972,33 @@ // the array should mirror the parameters below // note: all values past the year are optional and will default to the lowest possible value. // [year, month, day , hour, minute, second, millisecond] - function dateFromArray(config) { - var i, date, input = [], currentDate; + function dateFromConfig(config) { + var i, date, input = [], currentDate, yearToUse; if (config._d) { return; } + currentDate = currentDateArray(config); + + //if the day of the year is set, figure out what it is + if (config._dayOfYear) { + yearToUse = config._a[YEAR] == null ? currentDate[YEAR] : config._a[YEAR]; + + if (config._dayOfYear > (isLeapYear(yearToUse) ? 364 : 365)) { + config._pf._overflowDayOfYear = true; + } + + date = new Date(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getMonth(); + config._a[DATE] = date.getDate(); + } + // Default to current date. // * if no year, month, day of month are given, default to today // * if day of month is given, default month and year // * if month is given, default only year // * if year is given, don't default anything - currentDate = currentDateArray(config); for (i = 0; i < 3 && config._a[i] == null; ++i) { config._a[i] = input[i] = currentDate[i]; } @@ -1027,7 +1043,7 @@ normalizedInput.millisecond ]; - dateFromArray(config); + dateFromConfig(config); } function currentDateArray(config) { @@ -1098,7 +1114,7 @@ config._a[HOUR] = 0; } - dateFromArray(config); + dateFromConfig(config); checkOverflow(config); } @@ -1186,7 +1202,7 @@ makeDateFromString(config); } else if (isArray(input)) { config._a = input.slice(0); - dateFromArray(config); + dateFromConfig(config); } else if (isDate(input)) { config._d = new Date(+input); } else if (typeof(input) === 'object') { @@ -1498,8 +1514,7 @@ isDSTShifted : function () { if (this._a) { - //this is best-effort. What if it's a valid overflow AND DST-shifted? - return this.isValid() && !this._pf.overflowMonthOk && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0; + return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0; } return false; diff --git a/test/moment.parsing_flags.js b/test/moment.parsing_flags.js deleted file mode 100644 index 4a5d079c6..000000000 --- a/test/moment.parsing_flags.js +++ /dev/null @@ -1,178 +0,0 @@ -var moment = require('../../moment'), - flags = function () { - return moment.apply(null, arguments).parsingFlags(); - }; - -exports.parsing_flags = { - - 'overflow with array' : function (test) { - - //months - test.equal(flags([2010, 0]).overflow, -1, 'month 0 valid'); - test.equal(flags([2010, 1]).overflow, -1, 'month 1 valid'); - test.equal(flags([2010, -1]).overflow, 1, 'month -1 invalid'); - test.equal(flags([2100, 12]).overflow, 1, 'month 12 invalid'); - - //days - test.equal(flags([2010, 1, 16]).overflow, -1, 'date valid'); - test.equal(flags([2010, 1, -1]).overflow, 2, 'date -1 invalid'); - test.equal(flags([2010, 1, 0]).overflow, 2, 'date 0 invalid'); - test.equal(flags([2010, 1, 32]).overflow, 2, 'date 32 invalid'); - test.equal(flags([2012, 1, 29]).overflow, -1, 'date leap year valid'); - test.equal(flags([2010, 1, 29]).overflow, 2, 'date leap year invalid'); - - //hours - test.equal(flags([2010, 1, 1, 8]).overflow, -1, 'hour valid'); - test.equal(flags([2010, 1, 1, 0]).overflow, -1, 'hour 0 valid'); - test.equal(flags([2010, 1, 1, -1]).overflow, 3, 'hour -1 invalid'); - test.equal(flags([2010, 1, 1, 24]).overflow, 3, 'hour 24 invalid'); - - //minutes - test.equal(flags([2010, 1, 1, 8, 15]).overflow, -1, 'minute valid'); - test.equal(flags([2010, 1, 1, 8, 0]).overflow, -1, 'minute 0 valid'); - test.equal(flags([2010, 1, 1, 8, -1]).overflow, 4, 'minute -1 invalid'); - test.equal(flags([2010, 1, 1, 8, 60]).overflow, 4, 'minute 60 invalid'); - - //seconds - test.equal(flags([2010, 1, 1, 8, 15, 12]).overflow, -1, 'second valid'); - test.equal(flags([2010, 1, 1, 8, 15, 0]).overflow, -1, 'second 0 valid'); - test.equal(flags([2010, 1, 1, 8, 15, -1]).overflow, 5, 'second -1 invalid'); - test.equal(flags([2010, 1, 1, 8, 15, 60]).overflow, 5, 'second 60 invalid'); - - //milliseconds - test.equal(flags([2010, 1, 1, 8, 15, 12, 345]).overflow, -1, 'millisecond valid'); - test.equal(flags([2010, 1, 1, 8, 15, 12, 0]).overflow, -1, 'millisecond 0 valid'); - test.equal(flags([2010, 1, 1, 8, 15, 12, -1]).overflow, 6, 'millisecond -1 invalid'); - test.equal(flags([2010, 1, 1, 8, 15, 12, 1000]).overflow, 6, 'millisecond 1000 invalid'); - - test.done(); - }, - - 'overflow without format' : function (test) { - - //months - test.equal(flags('2001-01', 'YYYY-MM').overflow, -1, 'month 1 valid'); - test.equal(flags('2001-12', 'YYYY-MM').overflow, -1, 'month 12 valid'); - test.equal(flags('2001-13', 'YYYY-MM').overflow, 1, 'month 13 invalid'); - - //days - test.equal(flags('2010-01-16', 'YYYY-MM-DD').overflow, -1, 'date 16 valid'); - test.equal(flags('2010-01-0', 'YYYY-MM-DD').overflow, 2, 'date 0 invalid'); - test.equal(flags('2010-01-32', 'YYYY-MM-DD').overflow, 2, 'date 32 invalid'); - test.equal(flags('2012-02-29', 'YYYY-MM-DD').overflow, -1, 'date leap year valid'); - test.equal(flags('2010-02-29', 'YYYY-MM-DD').overflow, 2, 'date leap year invalid'); - - //days of the year - test.equal(flags('2010 300', 'YYYY DDDD').overflow, -1, 'day 300 of year valid'); - test.equal(flags('2010 365', 'YYYY DDDD').overflow, -1, 'day 365 of year valid'); - test.equal(flags('2010 366', 'YYYY DDDD').overflow, 2, 'day 366 of year invalid'); - test.equal(flags('2012 364', 'YYYY DDDD').overflow, -1, 'day 364 of leap year valid'); - test.equal(flags('2012 365', 'YYYY DDDD').overflow, 2, 'day 365 of leap year invalid'); - - //hours - test.equal(flags('08', 'HH').overflow, -1, 'hour valid'); - test.equal(flags('00', 'HH').overflow, -1, 'hour 0 valid'); - test.equal(flags('24', 'HH').overflow, 3, 'hour 24 invalid'); - - //minutes - test.equal(flags('08:15', 'HH:mm').overflow, -1, 'minute valid'); - test.equal(flags('08:00', 'HH:mm').overflow, -1, 'minute 0 valid'); - test.equal(flags('08:60', 'HH:mm').overflow, 4, 'minute 60 invalid'); - - //seconds - test.equal(flags('08:15:12', 'HH:mm:ss').overflow, -1, 'second valid'); - test.equal(flags('08:15:00', 'HH:mm:ss').overflow, -1, 'second 0 valid'); - test.equal(flags('08:15:60', 'HH:mm:ss').overflow, 5, 'second 60 invalid'); - - //milliseconds - test.equal(flags('08:15:12:345', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond valid'); - test.equal(flags('08:15:12:000', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond 0 valid'); - - //this is OK because we don't match the last digit, so it's 100 ms - test.equal(flags('08:15:12:1000', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond 1000 actually valid'); - - test.done(); - }, - - 'extra tokens' : function (test) { - - test.deepEqual(flags('1982-05-25', 'YYYY-MM-DD').unusedTokens, [], 'nothing extra'); - test.deepEqual(flags('1982-05', 'YYYY-MM-DD').unusedTokens, ['DD'], 'extra formatting token'); - test.deepEqual(flags('1982', 'YYYY-MM-DD').unusedTokens, ['MM', 'DD'], 'multiple extra formatting tokens'); - test.deepEqual(flags('1982-05', 'YYYY-MM-').unusedTokens, [], 'extra non-formatting token'); - test.deepEqual(flags('1982-05-', 'YYYY-MM-DD').unusedTokens, ['DD'], 'non-extra non-formatting token'); - test.deepEqual(flags('1982 05 1982', 'YYYY-MM-DD').unusedTokens, [], 'different non-formatting token'); - - test.done(); - }, - - 'extra tokens strict' : function (test) { - - test.deepEqual(flags('1982-05-25', 'YYYY-MM-DD', true).unusedTokens, [], 'nothing extra'); - test.deepEqual(flags('1982-05', 'YYYY-MM-DD', true).unusedTokens, ['-', 'DD'], 'extra formatting token'); - test.deepEqual(flags('1982', 'YYYY-MM-DD', true).unusedTokens, ['-', 'MM', '-', 'DD'], 'multiple extra formatting tokens'); - test.deepEqual(flags('1982-05', 'YYYY-MM-', true).unusedTokens, ['-'], 'extra non-formatting token'); - test.deepEqual(flags('1982-05-', 'YYYY-MM-DD', true).unusedTokens, ['DD'], 'non-extra non-formatting token'); - test.deepEqual(flags('1982 05 1982', 'YYYY-MM-DD', true).unusedTokens, ['-', '-'], 'different non-formatting token'); - - test.done(); - }, - - 'unused input' : function (test) { - test.deepEqual(flags('1982-05-25', 'YYYY-MM-DD').unusedInput, [], 'normal input'); - test.deepEqual(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').unusedInput, [' this is more stuff'], 'trailing nonsense'); - test.deepEqual(flags('1982-05-25 09:30', 'YYYY-MM-DD').unusedInput, [' 09:30'], ['trailing legit-looking input']); - test.deepEqual(flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]').unusedInput, [], 'junk that actually gets matched'); - test.deepEqual(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').unusedInput, ['stuff at beginning '], 'leading junk'); - test.deepEqual(flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD').unusedInput, ['junk ', ' more junk ', ' yet more junk'], 'interstitial junk'); - - test.done(); - }, - - 'unused input strict' : function (test) { - test.deepEqual(flags('1982-05-25', 'YYYY-MM-DD', true).unusedInput, [], 'normal input'); - test.deepEqual(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD', true).unusedInput, [' this is more stuff'], 'trailing nonsense'); - test.deepEqual(flags('1982-05-25 09:30', 'YYYY-MM-DD', true).unusedInput, [' 09:30'], ['trailing legit-looking input']); - test.deepEqual(flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]', true).unusedInput, [], 'junk that actually gets matched'); - test.deepEqual(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD', true).unusedInput, ['stuff at beginning '], 'leading junk'); - test.deepEqual(flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD', true).unusedInput, ['junk ', ' more junk ', ' yet more junk'], 'interstitial junk'); - - test.done(); - }, - - 'chars left over' : function (test) { - test.equal(flags('1982-05-25', 'YYYY-MM-DD').charsLeftOver, 0, 'normal input'); - test.equal(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').charsLeftOver, ' this is more stuff'.length, 'trailing nonsense'); - test.equal(flags('1982-05-25 09:30', 'YYYY-MM-DD').charsLeftOver, ' 09:30'.length, 'trailing legit-looking input'); - test.equal(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').charsLeftOver, 'stuff at beginning '.length, 'leading junk'); - test.equal(flags('1982 junk 05 more junk25', 'YYYY-MM-DD').charsLeftOver, [' junk ', ' more junk'].join('').length, 'interstitial junk'); - test.equal(flags('stuff at beginning 1982 junk 05 more junk25', 'YYYY-MM-DD').charsLeftOver, ['stuff at beginning ', ' junk ', ' more junk'].join('').length, 'leading and interstitial junk'); - - test.done(); - }, - - 'empty' : function (test) { - test.equal(flags('1982-05-25', 'YYYY-MM-DD').empty, false, 'normal input'); - test.equal(flags('nothing here', 'YYYY-MM-DD').empty, true, 'pure garbage'); - test.equal(flags('junk but has the number 2000 in it', 'YYYY-MM-DD').empty, false, 'only mostly garbage'); - test.equal(flags('', 'YYYY-MM-DD').empty, true, 'empty string'); - test.equal(flags('', 'YYYY-MM-DD').empty, true, 'blank string'); - - test.done(); - }, - - 'null' : function (test) { - test.equal(flags('1982-05-25', 'YYYY-MM-DD').nullInput, false, 'normal input'); - test.equal(flags(null).nullInput, true, 'just null'); - test.equal(flags(null, 'YYYY-MM-DD').nullInput, true, 'null with format'); - - test.done(); - }, - - 'invalid month' : function (test) { - test.equal(flags('1982 May', 'YYYY MMMM').invalidMonth, null, 'normal input'); - test.equal(flags('1982 Laser', 'YYYY MMMM').invalidMonth, 'Laser', 'bad month name'); - - test.done(); - } -}; diff --git a/test/moment/is_valid.js b/test/moment/is_valid.js index a4c8e74d6..216d0346b 100644 --- a/test/moment/is_valid.js +++ b/test/moment/is_valid.js @@ -240,6 +240,16 @@ exports.is_valid = { test.done(); }, + "days of the year" : function (test) { + test.equal(moment('2010 300', 'YYYY DDDD').isValid(), true, 'day 300 of year valid'); + test.equal(moment('2010 365', 'YYYY DDDD').isValid(), true, 'day 365 of year valid'); + test.equal(moment('2010 366', 'YYYY DDDD').isValid(), false, 'day 366 of year invalid'); + test.equal(moment('2012 364', 'YYYY DDDD').isValid(), true, 'day 364 of leap year valid'); + test.equal(moment('2012 365', 'YYYY DDDD').isValid(), false, 'day 365 of leap year invalid'); + + test.done(); + }, + "oddball permissiveness" : function (test) { //https://github.com/moment/moment/issues/1128 test.ok(moment("2010-10-3199", ["MM/DD/YYYY", "MM-DD-YYYY", "YYYY-MM-DD"]).isValid());