vendor: 5,992 bytes, lines 1-223
1//! moment.js 2 3; (function (global, factory) { 4 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 5 typeof define === 'function' && define.amd ? define(factory) : 6 global.moment = factory() 7 }(this, (function () { 8 'use strict'; 9 10 var hookCallback; 11 12 function hooks () { 13 return hookCallback.apply(null, arguments); 14 } 15 16 // This is done to register the method called with moment() 17 // without creating circular dependencies. 18 function setHookCallback (callback) { 19 hookCallback = callback; 20 } 21 22 function isArray (input) { 23 return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; 24 } 25 26 function isObject (input) { 27 // IE8 will treat undefined and null as object if it wasn't for 28 // input != null 29 return input != null && Object.prototype.toString.call(input) === '[object Object]'; 30 } 31 32 function isObjectEmpty (obj) { 33 if (Object.getOwnPropertyNames) { 34 return (Object.getOwnPropertyNames(obj).length === 0); 35 } else { 36 var k; 37 for (k in obj) { 38 if (obj.hasOwnProperty(k)) { 39 return false; 40 } 41 } 42 return true; 43 } 44 } 45 46 function isUndefined (input) { 47 return input === void 0; 48 } 49 50 function isNumber (input) { 51 return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; 52 } 53 54 function isDate (input) { 55 return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; 56 } 57 58 function map (arr, fn) { 59 var res = [], i; 60 for (i = 0; i < arr.length; ++i) { 61 res.push(fn(arr[i], i)); 62 } 63 return res; 64 } 65 66 function hasOwnProp (a, b) { 67 return Object.prototype.hasOwnProperty.call(a, b); 68 } 69 70 function extend (a, b) { 71 for (var i in b) { 72 if (hasOwnProp(b, i)) { 73 a[i] = b[i]; 74 } 75 } 76 77 if (hasOwnProp(b, 'toString')) { 78 a.toString = b.toString; 79 } 80 81 if (hasOwnProp(b, 'valueOf')) { 82 a.valueOf = b.valueOf; 83 } 84 85 return a; 86 } 87 88 function createUTC (input, format, locale, strict) { 89 return createLocalOrUTC(input, format, locale, strict, true).utc(); 90 } 91 92 function defaultParsingFlags () { 93 // We need to deep clone this object. 94 return { 95 empty: false, 96 unusedTokens: [], 97 unusedInput: [], 98 overflow: -2, 99 charsLeftOver: 0, 100 nullInput: false, 101 invalidMonth: null, 102 invalidFormat: false, 103 userInvalidated: false, 104 iso: false, 105 parsedDateParts: [], 106 meridiem: null, 107 rfc2822: false, 108 weekdayMismatch: false 109 }; 110 } 111 112 function getParsingFlags (m) { 113 if (m._pf == null) { 114 m._pf = defaultParsingFlags(); 115 } 116 return m._pf; 117 } 118 119 var some; 120 if (Array.prototype.some) { 121 some = Array.prototype.some; 122 } else { 123 some = function (fun) { 124 var t = Object(this); 125 var len = t.length >>> 0; 126 127 for (var i = 0; i < len; i++) { 128 if (i in t && fun.call(this, t[i], i, t)) { 129 return true; 130 } 131 } 132 133 return false; 134 }; 135 } 136 137 function isValid (m) { 138 if (m._isValid == null) { 139 var flags = getParsingFlags(m); 140 var parsedParts = some.call(flags.parsedDateParts, function (i) { 141 return i != null; 142 }); 143 var isNowValid = !isNaN(m._d.getTime()) && 144 flags.overflow < 0 && 145 !flags.empty && 146 !flags.invalidMonth && 147 !flags.invalidWeekday && 148 !flags.weekdayMismatch && 149 !flags.nullInput && 150 !flags.invalidFormat && 151 !flags.userInvalidated && 152 (!flags.meridiem || (flags.meridiem && parsedParts)); 153 154 if (m._strict) { 155 isNowValid = isNowValid && 156 flags.charsLeftOver === 0 && 157 flags.unusedTokens.length === 0 && 158 flags.bigHour === undefined; 159 } 160 161 if (Object.isFrozen == null || !Object.isFrozen(m)) { 162 m._isValid = isNowValid; 163 } 164 else { 165 return isNowValid; 166 } 167 } 168 return m._isValid; 169 } 170 171 function createInvalid (flags) { 172 var m = createUTC(NaN); 173 if (flags != null) { 174 extend(getParsingFlags(m), flags); 175 } 176 else { 177 getParsingFlags(m).userInvalidated = true; 178 } 179 180 return m; 181 } 182 183 // Plugins that add properties should also add the key here (null value), 184 // so we can properly clone ourselves. 185 var momentProperties = hooks.momentProperties = []; 186 187 function copyConfig (to, from) { 188 var i, prop, val; 189 190 if (!isUndefined(from._isAMomentObject)) { 191 to._isAMomentObject = from._isAMomentObject; 192 } 193 if (!isUndefined(from._i)) { 194 to._i = from._i; 195 } 196 if (!isUndefined(from._f)) { 197 to._f = from._f; 198 } 199 if (!isUndefined(from._l)) { 200 to._l = from._l; 201 } 202 if (!isUndefined(from._strict)) { 203 to._strict = from._strict; 204 } 205 if (!isUndefined(from._tzm)) { 206 to._tzm = from._tzm; 207 } 208 if (!isUndefined(from._isUTC)) { 209 to._isUTC = from._isUTC; 210 } 211 if (!isUndefined(from._offset)) { 212 to._offset = from._offset; 213 } 214 if (!isUndefined(from._pf)) { 215 to._pf = getParsingFlags(from); 216 } 217 if (!isUndefined(from._locale)) { 218 to._locale = from._locale; 219 } 220 221 if (momentProperties.length > 0) { 222 for (i = 0; i < momentProperties.length; i++) { 223 prop = momentProperties[i];
vendor: 137,305 bytes, lines 224-4544
224 val = from[prop]; 225 if (!isUndefined(val)) { 226 to[prop] = val; 227 } 228 } 229 } 230 231 return to; 232 } 233 234 var updateInProgress = false; 235 236 // Moment prototype object 237 function Moment (config) { 238 copyConfig(this, config); 239 this._d = new Date(config._d != null ? config._d.getTime() : NaN); 240 if (!this.isValid()) { 241 this._d = new Date(NaN); 242 } 243 // Prevent infinite loop in case updateOffset creates new moment 244 // objects. 245 if (updateInProgress === false) { 246 updateInProgress = true; 247 hooks.updateOffset(this); 248 updateInProgress = false; 249 } 250 } 251 252 function isMoment (obj) { 253 return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); 254 } 255 256 function absFloor (number) { 257 if (number < 0) { 258 // -0 -> 0 259 return Math.ceil(number) || 0; 260 } else { 261 return Math.floor(number); 262 } 263 } 264 265 function toInt (argumentForCoercion) { 266 var coercedNumber = +argumentForCoercion, 267 value = 0; 268 269 if (coercedNumber !== 0 && isFinite(coercedNumber)) { 270 value = absFloor(coercedNumber); 271 } 272 273 return value; 274 } 275 276 // compare two arrays, return the number of differences 277 function compareArrays (array1, array2, dontConvert) { 278 var len = Math.min(array1.length, array2.length), 279 lengthDiff = Math.abs(array1.length - array2.length), 280 diffs = 0, 281 i; 282 for (i = 0; i < len; i++) { 283 if ((dontConvert && array1[i] !== array2[i]) || 284 (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { 285 diffs++; 286 } 287 } 288 return diffs + lengthDiff; 289 } 290 291 function warn (msg) { 292 if (hooks.suppressDeprecationWarnings === false && 293 (typeof console !== 'undefined') && console.warn) { 294 console.warn('Deprecation warning: ' + msg); 295 } 296 } 297 298 function deprecate (msg, fn) { 299 var firstTime = true; 300 301 return extend(function () { 302 if (hooks.deprecationHandler != null) { 303 hooks.deprecationHandler(null, msg); 304 } 305 if (firstTime) { 306 var args = []; 307 var arg; 308 for (var i = 0; i < arguments.length; i++) { 309 arg = ''; 310 if (typeof arguments[i] === 'object') { 311 arg += '\n[' + i + '] '; 312 for (var key in arguments[0]) { 313 arg += key + ': ' + arguments[0][key] + ', '; 314 } 315 arg = arg.slice(0, -2); // Remove trailing comma and space 316 } else { 317 arg = arguments[i]; 318 } 319 args.push(arg); 320 } 321 warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); 322 firstTime = false; 323 } 324 return fn.apply(this, arguments); 325 }, fn); 326 } 327 328 var deprecations = {}; 329 330 function deprecateSimple (name, msg) { 331 if (hooks.deprecationHandler != null) { 332 hooks.deprecationHandler(name, msg); 333 } 334 if (!deprecations[name]) { 335 warn(msg); 336 deprecations[name] = true; 337 } 338 } 339 340 hooks.suppressDeprecationWarnings = false; 341 hooks.deprecationHandler = null; 342 343 function isFunction (input) { 344 return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; 345 } 346 347 function set (config) { 348 var prop, i; 349 for (i in config) { 350 prop = config[i]; 351 if (isFunction(prop)) { 352 this[i] = prop; 353 } else { 354 this['_' + i] = prop; 355 } 356 } 357 this._config = config; 358 // Lenient ordinal parsing accepts just a number in addition to 359 // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. 360 // TODO: Remove "ordinalParse" fallback in next major release. 361 this._dayOfMonthOrdinalParseLenient = new RegExp( 362 (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + 363 '|' + (/\d{1,2}/).source); 364 } 365 366 function mergeConfigs (parentConfig, childConfig) { 367 var res = extend({}, parentConfig), prop; 368 for (prop in childConfig) { 369 if (hasOwnProp(childConfig, prop)) { 370 if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { 371 res[prop] = {}; 372 extend(res[prop], parentConfig[prop]); 373 extend(res[prop], childConfig[prop]); 374 } else if (childConfig[prop] != null) { 375 res[prop] = childConfig[prop]; 376 } else { 377 delete res[prop]; 378 } 379 } 380 } 381 for (prop in parentConfig) { 382 if (hasOwnProp(parentConfig, prop) && 383 !hasOwnProp(childConfig, prop) && 384 isObject(parentConfig[prop])) { 385 // make sure changes to properties don't modify parent config 386 res[prop] = extend({}, res[prop]); 387 } 388 } 389 return res; 390 } 391 392 function Locale (config) { 393 if (config != null) { 394 this.set(config); 395 } 396 } 397 398 var keys; 399 400 if (Object.keys) { 401 keys = Object.keys; 402 } else { 403 keys = function (obj) { 404 var i, res = []; 405 for (i in obj) { 406 if (hasOwnProp(obj, i)) { 407 res.push(i); 408 } 409 } 410 return res; 411 }; 412 } 413 414 var defaultCalendar = { 415 sameDay: '[Today at] LT', 416 nextDay: '[Tomorrow at] LT', 417 nextWeek: 'dddd [at] LT', 418 lastDay: '[Yesterday at] LT', 419 lastWeek: '[Last] dddd [at] LT', 420 sameElse: 'L' 421 }; 422 423 function calendar (key, mom, now) { 424 var output = this._calendar[key] || this._calendar['sameElse']; 425 return isFunction(output) ? output.call(mom, now) : output; 426 } 427 428 var defaultLongDateFormat = { 429 LTS: 'h:mm:ss A', 430 LT: 'h:mm A', 431 L: 'MM/DD/YYYY', 432 LL: 'MMMM D, YYYY', 433 LLL: 'MMMM D, YYYY h:mm A', 434 LLLL: 'dddd, MMMM D, YYYY h:mm A' 435 }; 436 437 function longDateFormat (key) { 438 var format = this._longDateFormat[key], 439 formatUpper = this._longDateFormat[key.toUpperCase()]; 440 441 if (format || !formatUpper) { 442 return format; 443 } 444 445 this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { 446 return val.slice(1); 447 }); 448 449 return this._longDateFormat[key]; 450 } 451 452 var defaultInvalidDate = 'Invalid date'; 453 454 function invalidDate () { 455 return this._invalidDate; 456 } 457 458 var defaultOrdinal = '%d'; 459 var defaultDayOfMonthOrdinalParse = /\d{1,2}/; 460 461 function ordinal (number) { 462 return this._ordinal.replace('%d', number); 463 } 464 465 var defaultRelativeTime = { 466 future: 'in %s', 467 past: '%s ago', 468 s: 'a few seconds', 469 ss: '%d seconds', 470 m: 'a minute', 471 mm: '%d minutes', 472 h: 'an hour', 473 hh: '%d hours', 474 d: 'a day', 475 dd: '%d days', 476 M: 'a month', 477 MM: '%d months', 478 y: 'a year', 479 yy: '%d years' 480 }; 481 482 function relativeTime (number, withoutSuffix, string, isFuture) { 483 var output = this._relativeTime[string]; 484 return (isFunction(output)) ? 485 output(number, withoutSuffix, string, isFuture) : 486 output.replace(/%d/i, number); 487 } 488 489 function pastFuture (diff, output) { 490 var format = this._relativeTime[diff > 0 ? 'future' : 'past']; 491 return isFunction(format) ? format(output) : format.replace(/%s/i, output); 492 } 493 494 var aliases = {}; 495 496 function addUnitAlias (unit, shorthand) { 497 var lowerCase = unit.toLowerCase(); 498 aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; 499 } 500 501 function normalizeUnits (units) { 502 return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; 503 } 504 505 function normalizeObjectUnits (inputObject) { 506 var normalizedInput = {}, 507 normalizedProp, 508 prop; 509 510 for (prop in inputObject) { 511 if (hasOwnProp(inputObject, prop)) { 512 normalizedProp = normalizeUnits(prop); 513 if (normalizedProp) { 514 normalizedInput[normalizedProp] = inputObject[prop]; 515 } 516 } 517 } 518 519 return normalizedInput; 520 } 521 522 var priorities = {}; 523 524 function addUnitPriority (unit, priority) { 525 priorities[unit] = priority; 526 } 527 528 function getPrioritizedUnits (unitsObj) { 529 var units = []; 530 for (var u in unitsObj) { 531 units.push({ unit: u, priority: priorities[u] }); 532 } 533 units.sort(function (a, b) { 534 return a.priority - b.priority; 535 }); 536 return units; 537 } 538 539 function zeroFill (number, targetLength, forceSign) { 540 var absNumber = '' + Math.abs(number), 541 zerosToFill = targetLength - absNumber.length, 542 sign = number >= 0; 543 return (sign ? (forceSign ? '+' : '') : '-') + 544 Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; 545 } 546 547 var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; 548 549 var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; 550 551 var formatFunctions = {}; 552 553 var formatTokenFunctions = {}; 554 555 // token: 'M' 556 // padded: ['MM', 2] 557 // ordinal: 'Mo' 558 // callback: function () { this.month() + 1 } 559 function addFormatToken (token, padded, ordinal, callback) { 560 var func = callback; 561 if (typeof callback === 'string') { 562 func = function () { 563 return this[callback](); 564 }; 565 } 566 if (token) { 567 formatTokenFunctions[token] = func; 568 } 569 if (padded) { 570 formatTokenFunctions[padded[0]] = function () { 571 return zeroFill(func.apply(this, arguments), padded[1], padded[2]); 572 }; 573 } 574 if (ordinal) { 575 formatTokenFunctions[ordinal] = function () { 576 return this.localeData().ordinal(func.apply(this, arguments), token); 577 }; 578 } 579 } 580 581 function removeFormattingTokens (input) { 582 if (input.match(/\[[\s\S]/)) { 583 return input.replace(/^\[|\]$/g, ''); 584 } 585 return input.replace(/\\/g, ''); 586 } 587 588 function makeFormatFunction (format) { 589 var array = format.match(formattingTokens), i, length; 590 591 for (i = 0, length = array.length; i < length; i++) { 592 if (formatTokenFunctions[array[i]]) { 593 array[i] = formatTokenFunctions[array[i]]; 594 } else { 595 array[i] = removeFormattingTokens(array[i]); 596 } 597 } 598 599 return function (mom) { 600 var output = '', i; 601 for (i = 0; i < length; i++) { 602 output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; 603 } 604 return output; 605 }; 606 } 607 608 // format date using native date object 609 function formatMoment (m, format) { 610 if (!m.isValid()) { 611 return m.localeData().invalidDate(); 612 } 613 614 format = expandFormat(format, m.localeData()); 615 formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); 616 617 return formatFunctions[format](m); 618 } 619 620 function expandFormat (format, locale) { 621 var i = 5; 622 623 function replaceLongDateFormatTokens (input) { 624 return locale.longDateFormat(input) || input; 625 } 626 627 localFormattingTokens.lastIndex = 0; 628 while (i >= 0 && localFormattingTokens.test(format)) { 629 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); 630 localFormattingTokens.lastIndex = 0; 631 i -= 1; 632 } 633 634 return format; 635 } 636 637 var match1 = /\d/; // 0 - 9 638 var match2 = /\d\d/; // 00 - 99 639 var match3 = /\d{3}/; // 000 - 999 640 var match4 = /\d{4}/; // 0000 - 9999 641 var match6 = /[+-]?\d{6}/; // -999999 - 999999 642 var match1to2 = /\d\d?/; // 0 - 99 643 var match3to4 = /\d\d\d\d?/; // 999 - 9999 644 var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 645 var match1to3 = /\d{1,3}/; // 0 - 999 646 var match1to4 = /\d{1,4}/; // 0 - 9999 647 var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 648 649 var matchUnsigned = /\d+/; // 0 - inf 650 var matchSigned = /[+-]?\d+/; // -inf - inf 651 652 var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z 653 var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z 654 655 var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 656 657 // any word (or two) characters or numbers including two/three word month in arabic. 658 // includes scottish gaelic two word and hyphenated months 659 var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; 660 661 var regexes = {}; 662 663 function addRegexToken (token, regex, strictRegex) { 664 regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { 665 return (isStrict && strictRegex) ? strictRegex : regex; 666 }; 667 } 668 669 function getParseRegexForToken (token, config) { 670 if (!hasOwnProp(regexes, token)) { 671 return new RegExp(unescapeFormat(token)); 672 } 673 674 return regexes[token](config._strict, config._locale); 675 } 676 677 // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript 678 function unescapeFormat (s) { 679 return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { 680 return p1 || p2 || p3 || p4; 681 })); 682 } 683 684 function regexEscape (s) { 685 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); 686 } 687 688 var tokens = {}; 689 690 function addParseToken (token, callback) { 691 var i, func = callback; 692 if (typeof token === 'string') { 693 token = [token]; 694 } 695 if (isNumber(callback)) { 696 func = function (input, array) { 697 array[callback] = toInt(input); 698 }; 699 } 700 for (i = 0; i < token.length; i++) { 701 tokens[token[i]] = func; 702 } 703 } 704 705 function addWeekParseToken (token, callback) { 706 addParseToken(token, function (input, array, config, token) { 707 config._w = config._w || {}; 708 callback(input, config._w, config, token); 709 }); 710 } 711 712 function addTimeToArrayFromToken (token, input, config) { 713 if (input != null && hasOwnProp(tokens, token)) { 714 tokens[token](input, config._a, config, token); 715 } 716 } 717 718 var YEAR = 0; 719 var MONTH = 1; 720 var DATE = 2; 721 var HOUR = 3; 722 var MINUTE = 4; 723 var SECOND = 5; 724 var MILLISECOND = 6; 725 var WEEK = 7; 726 var WEEKDAY = 8; 727 728 // FORMATTING 729 730 addFormatToken('Y', 0, 0, function () { 731 var y = this.year(); 732 return y <= 9999 ? '' + y : '+' + y; 733 }); 734 735 addFormatToken(0, ['YY', 2], 0, function () { 736 return this.year() % 100; 737 }); 738 739 addFormatToken(0, ['YYYY', 4], 0, 'year'); 740 addFormatToken(0, ['YYYYY', 5], 0, 'year'); 741 addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); 742 743 // ALIASES 744 745 addUnitAlias('year', 'y'); 746 747 // PRIORITIES 748 749 addUnitPriority('year', 1); 750 751 // PARSING 752 753 addRegexToken('Y', matchSigned); 754 addRegexToken('YY', match1to2, match2); 755 addRegexToken('YYYY', match1to4, match4); 756 addRegexToken('YYYYY', match1to6, match6); 757 addRegexToken('YYYYYY', match1to6, match6); 758 759 addParseToken(['YYYYY', 'YYYYYY'], YEAR); 760 addParseToken('YYYY', function (input, array) { 761 array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); 762 }); 763 addParseToken('YY', function (input, array) { 764 array[YEAR] = hooks.parseTwoDigitYear(input); 765 }); 766 addParseToken('Y', function (input, array) { 767 array[YEAR] = parseInt(input, 10); 768 }); 769 770 // HELPERS 771 772 function daysInYear (year) { 773 return isLeapYear(year) ? 366 : 365; 774 } 775 776 function isLeapYear (year) { 777 return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; 778 } 779 780 // HOOKS 781 782 hooks.parseTwoDigitYear = function (input) { 783 return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); 784 }; 785 786 // MOMENTS 787 788 var getSetYear = makeGetSet('FullYear', true); 789 790 function getIsLeapYear () { 791 return isLeapYear(this.year()); 792 } 793 794 function makeGetSet (unit, keepTime) { 795 return function (value) { 796 if (value != null) { 797 set$1(this, unit, value); 798 hooks.updateOffset(this, keepTime); 799 return this; 800 } else { 801 return get(this, unit); 802 } 803 }; 804 } 805 806 function get (mom, unit) { 807 return mom.isValid() ? 808 mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; 809 } 810 811 function set$1 (mom, unit, value) { 812 if (mom.isValid() && !isNaN(value)) { 813 if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { 814 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); 815 } 816 else { 817 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); 818 } 819 } 820 } 821 822 // MOMENTS 823 824 function stringGet (units) { 825 units = normalizeUnits(units); 826 if (isFunction(this[units])) { 827 return this[units](); 828 } 829 return this; 830 } 831 832 833 function stringSet (units, value) { 834 if (typeof units === 'object') { 835 units = normalizeObjectUnits(units); 836 var prioritized = getPrioritizedUnits(units); 837 for (var i = 0; i < prioritized.length; i++) { 838 this[prioritized[i].unit](units[prioritized[i].unit]); 839 } 840 } else { 841 units = normalizeUnits(units); 842 if (isFunction(this[units])) { 843 return this[units](value); 844 } 845 } 846 return this; 847 } 848 849 function mod (n, x) { 850 return ((n % x) + x) % x; 851 } 852 853 var indexOf; 854 855 if (Array.prototype.indexOf) { 856 indexOf = Array.prototype.indexOf; 857 } else { 858 indexOf = function (o) { 859 // I know 860 var i; 861 for (i = 0; i < this.length; ++i) { 862 if (this[i] === o) { 863 return i; 864 } 865 } 866 return -1; 867 }; 868 } 869 870 function daysInMonth (year, month) { 871 if (isNaN(year) || isNaN(month)) { 872 return NaN; 873 } 874 var modMonth = mod(month, 12); 875 year += (month - modMonth) / 12; 876 return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); 877 } 878 879 // FORMATTING 880 881 addFormatToken('M', ['MM', 2], 'Mo', function () { 882 return this.month() + 1; 883 }); 884 885 addFormatToken('MMM', 0, 0, function (format) { 886 return this.localeData().monthsShort(this, format); 887 }); 888 889 addFormatToken('MMMM', 0, 0, function (format) { 890 return this.localeData().months(this, format); 891 }); 892 893 // ALIASES 894 895 addUnitAlias('month', 'M'); 896 897 // PRIORITY 898 899 addUnitPriority('month', 8); 900 901 // PARSING 902 903 addRegexToken('M', match1to2); 904 addRegexToken('MM', match1to2, match2); 905 addRegexToken('MMM', function (isStrict, locale) { 906 return locale.monthsShortRegex(isStrict); 907 }); 908 addRegexToken('MMMM', function (isStrict, locale) { 909 return locale.monthsRegex(isStrict); 910 }); 911 912 addParseToken(['M', 'MM'], function (input, array) { 913 array[MONTH] = toInt(input) - 1; 914 }); 915 916 addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { 917 var month = config._locale.monthsParse(input, token, config._strict); 918 // if we didn't find a month name, mark the date as invalid. 919 if (month != null) { 920 array[MONTH] = month; 921 } else { 922 getParsingFlags(config).invalidMonth = input; 923 } 924 }); 925 926 // LOCALES 927 928 var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; 929 var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); 930 function localeMonths (m, format) { 931 if (!m) { 932 return isArray(this._months) ? this._months : 933 this._months['standalone']; 934 } 935 return isArray(this._months) ? this._months[m.month()] : 936 this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; 937 } 938 939 var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); 940 function localeMonthsShort (m, format) { 941 if (!m) { 942 return isArray(this._monthsShort) ? this._monthsShort : 943 this._monthsShort['standalone']; 944 } 945 return isArray(this._monthsShort) ? this._monthsShort[m.month()] : 946 this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; 947 } 948 949 function handleStrictParse (monthName, format, strict) { 950 var i, ii, mom, llc = monthName.toLocaleLowerCase(); 951 if (!this._monthsParse) { 952 // this is not used 953 this._monthsParse = []; 954 this._longMonthsParse = []; 955 this._shortMonthsParse = []; 956 for (i = 0; i < 12; ++i) { 957 mom = createUTC([2000, i]); 958 this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); 959 this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); 960 } 961 } 962 963 if (strict) { 964 if (format === 'MMM') { 965 ii = indexOf.call(this._shortMonthsParse, llc); 966 return ii !== -1 ? ii : null; 967 } else { 968 ii = indexOf.call(this._longMonthsParse, llc); 969 return ii !== -1 ? ii : null; 970 } 971 } else { 972 if (format === 'MMM') { 973 ii = indexOf.call(this._shortMonthsParse, llc); 974 if (ii !== -1) { 975 return ii; 976 } 977 ii = indexOf.call(this._longMonthsParse, llc); 978 return ii !== -1 ? ii : null; 979 } else { 980 ii = indexOf.call(this._longMonthsParse, llc); 981 if (ii !== -1) { 982 return ii; 983 } 984 ii = indexOf.call(this._shortMonthsParse, llc); 985 return ii !== -1 ? ii : null; 986 } 987 } 988 } 989 990 function localeMonthsParse (monthName, format, strict) { 991 var i, mom, regex; 992 993 if (this._monthsParseExact) { 994 return handleStrictParse.call(this, monthName, format, strict); 995 } 996 997 if (!this._monthsParse) { 998 this._monthsParse = []; 999 this._longMonthsParse = []; 1000 this._shortMonthsParse = []; 1001 } 1002 1003 // TODO: add sorting 1004 // Sorting makes sure if one month (or abbr) is a prefix of another 1005 // see sorting in computeMonthsParse 1006 for (i = 0; i < 12; i++) { 1007 // make the regex if we don't have it already 1008 mom = createUTC([2000, i]); 1009 if (strict && !this._longMonthsParse[i]) { 1010 this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); 1011 this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); 1012 } 1013 if (!strict && !this._monthsParse[i]) { 1014 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); 1015 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); 1016 } 1017 // test the regex 1018 if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { 1019 return i; 1020 } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { 1021 return i; 1022 } else if (!strict && this._monthsParse[i].test(monthName)) { 1023 return i; 1024 } 1025 } 1026 } 1027 1028 // MOMENTS 1029 1030 function setMonth (mom, value) { 1031 var dayOfMonth; 1032 1033 if (!mom.isValid()) { 1034 // No op 1035 return mom; 1036 } 1037 1038 if (typeof value === 'string') { 1039 if (/^\d+$/.test(value)) { 1040 value = toInt(value); 1041 } else { 1042 value = mom.localeData().monthsParse(value); 1043 // TODO: Another silent failure? 1044 if (!isNumber(value)) { 1045 return mom; 1046 } 1047 } 1048 } 1049 1050 dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); 1051 mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); 1052 return mom; 1053 } 1054 1055 function getSetMonth (value) { 1056 if (value != null) { 1057 setMonth(this, value); 1058 hooks.updateOffset(this, true); 1059 return this; 1060 } else { 1061 return get(this, 'Month'); 1062 } 1063 } 1064 1065 function getDaysInMonth () { 1066 return daysInMonth(this.year(), this.month()); 1067 } 1068 1069 var defaultMonthsShortRegex = matchWord; 1070 function monthsShortRegex (isStrict) { 1071 if (this._monthsParseExact) { 1072 if (!hasOwnProp(this, '_monthsRegex')) { 1073 computeMonthsParse.call(this); 1074 } 1075 if (isStrict) { 1076 return this._monthsShortStrictRegex; 1077 } else { 1078 return this._monthsShortRegex; 1079 } 1080 } else { 1081 if (!hasOwnProp(this, '_monthsShortRegex')) { 1082 this._monthsShortRegex = defaultMonthsShortRegex; 1083 } 1084 return this._monthsShortStrictRegex && isStrict ? 1085 this._monthsShortStrictRegex : this._monthsShortRegex; 1086 } 1087 } 1088 1089 var defaultMonthsRegex = matchWord; 1090 function monthsRegex (isStrict) { 1091 if (this._monthsParseExact) { 1092 if (!hasOwnProp(this, '_monthsRegex')) { 1093 computeMonthsParse.call(this); 1094 } 1095 if (isStrict) { 1096 return this._monthsStrictRegex; 1097 } else { 1098 return this._monthsRegex; 1099 } 1100 } else { 1101 if (!hasOwnProp(this, '_monthsRegex')) { 1102 this._monthsRegex = defaultMonthsRegex; 1103 } 1104 return this._monthsStrictRegex && isStrict ? 1105 this._monthsStrictRegex : this._monthsRegex; 1106 } 1107 } 1108 1109 function computeMonthsParse () { 1110 function cmpLenRev (a, b) { 1111 return b.length - a.length; 1112 } 1113 1114 var shortPieces = [], longPieces = [], mixedPieces = [], 1115 i, mom; 1116 for (i = 0; i < 12; i++) { 1117 // make the regex if we don't have it already 1118 mom = createUTC([2000, i]); 1119 shortPieces.push(this.monthsShort(mom, '')); 1120 longPieces.push(this.months(mom, '')); 1121 mixedPieces.push(this.months(mom, '')); 1122 mixedPieces.push(this.monthsShort(mom, '')); 1123 } 1124 // Sorting makes sure if one month (or abbr) is a prefix of another it 1125 // will match the longer piece. 1126 shortPieces.sort(cmpLenRev); 1127 longPieces.sort(cmpLenRev); 1128 mixedPieces.sort(cmpLenRev); 1129 for (i = 0; i < 12; i++) { 1130 shortPieces[i] = regexEscape(shortPieces[i]); 1131 longPieces[i] = regexEscape(longPieces[i]); 1132 } 1133 for (i = 0; i < 24; i++) { 1134 mixedPieces[i] = regexEscape(mixedPieces[i]); 1135 } 1136 1137 this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); 1138 this._monthsShortRegex = this._monthsRegex; 1139 this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); 1140 this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); 1141 } 1142 1143 function createDate (y, m, d, h, M, s, ms) { 1144 // can't just apply() to create a date: 1145 // https://stackoverflow.com/q/181348 1146 var date; 1147 // the date constructor remaps years 0-99 to 1900-1999 1148 if (y < 100 && y >= 0) { 1149 // preserve leap years using a full 400 year cycle, then reset 1150 date = new Date(y + 400, m, d, h, M, s, ms); 1151 if (isFinite(date.getFullYear())) { 1152 date.setFullYear(y); 1153 } 1154 } else { 1155 date = new Date(y, m, d, h, M, s, ms); 1156 } 1157 1158 return date; 1159 } 1160 1161 function createUTCDate (y) { 1162 var date; 1163 // the Date.UTC function remaps years 0-99 to 1900-1999 1164 if (y < 100 && y >= 0) { 1165 var args = Array.prototype.slice.call(arguments); 1166 // preserve leap years using a full 400 year cycle, then reset 1167 args[0] = y + 400; 1168 date = new Date(Date.UTC.apply(null, args)); 1169 if (isFinite(date.getUTCFullYear())) { 1170 date.setUTCFullYear(y); 1171 } 1172 } else { 1173 date = new Date(Date.UTC.apply(null, arguments)); 1174 } 1175 1176 return date; 1177 } 1178 1179 // start-of-first-week - start-of-year 1180 function firstWeekOffset (year, dow, doy) { 1181 var // first-week day -- which january is always in the first week (4 for iso, 1 for other) 1182 fwd = 7 + dow - doy, 1183 // first-week day local weekday -- which local weekday is fwd 1184 fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; 1185 1186 return -fwdlw + fwd - 1; 1187 } 1188 1189 // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday 1190 function dayOfYearFromWeeks (year, week, weekday, dow, doy) { 1191 var localWeekday = (7 + weekday - dow) % 7, 1192 weekOffset = firstWeekOffset(year, dow, doy), 1193 dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, 1194 resYear, resDayOfYear; 1195 1196 if (dayOfYear <= 0) { 1197 resYear = year - 1; 1198 resDayOfYear = daysInYear(resYear) + dayOfYear; 1199 } else if (dayOfYear > daysInYear(year)) { 1200 resYear = year + 1; 1201 resDayOfYear = dayOfYear - daysInYear(year); 1202 } else { 1203 resYear = year; 1204 resDayOfYear = dayOfYear; 1205 } 1206 1207 return { 1208 year: resYear, 1209 dayOfYear: resDayOfYear 1210 }; 1211 } 1212 1213 function weekOfYear (mom, dow, doy) { 1214 var weekOffset = firstWeekOffset(mom.year(), dow, doy), 1215 week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, 1216 resWeek, resYear; 1217 1218 if (week < 1) { 1219 resYear = mom.year() - 1; 1220 resWeek = week + weeksInYear(resYear, dow, doy); 1221 } else if (week > weeksInYear(mom.year(), dow, doy)) { 1222 resWeek = week - weeksInYear(mom.year(), dow, doy); 1223 resYear = mom.year() + 1; 1224 } else { 1225 resYear = mom.year(); 1226 resWeek = week; 1227 } 1228 1229 return { 1230 week: resWeek, 1231 year: resYear 1232 }; 1233 } 1234 1235 function weeksInYear (year, dow, doy) { 1236 var weekOffset = firstWeekOffset(year, dow, doy), 1237 weekOffsetNext = firstWeekOffset(year + 1, dow, doy); 1238 return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; 1239 } 1240 1241 // FORMATTING 1242 1243 addFormatToken('w', ['ww', 2], 'wo', 'week'); 1244 addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); 1245 1246 // ALIASES 1247 1248 addUnitAlias('week', 'w'); 1249 addUnitAlias('isoWeek', 'W'); 1250 1251 // PRIORITIES 1252 1253 addUnitPriority('week', 5); 1254 addUnitPriority('isoWeek', 5); 1255 1256 // PARSING 1257 1258 addRegexToken('w', match1to2); 1259 addRegexToken('ww', match1to2, match2); 1260 addRegexToken('W', match1to2); 1261 addRegexToken('WW', match1to2, match2); 1262 1263 addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { 1264 week[token.substr(0, 1)] = toInt(input); 1265 }); 1266 1267 // HELPERS 1268 1269 // LOCALES 1270 1271 function localeWeek (mom) { 1272 return weekOfYear(mom, this._week.dow, this._week.doy).week; 1273 } 1274 1275 var defaultLocaleWeek = { 1276 dow: 0, // Sunday is the first day of the week. 1277 doy: 6 // The week that contains Jan 6th is the first week of the year. 1278 }; 1279 1280 function localeFirstDayOfWeek () { 1281 return this._week.dow; 1282 } 1283 1284 function localeFirstDayOfYear () { 1285 return this._week.doy; 1286 } 1287 1288 // MOMENTS 1289 1290 function getSetWeek (input) { 1291 var week = this.localeData().week(this); 1292 return input == null ? week : this.add((input - week) * 7, 'd'); 1293 } 1294 1295 function getSetISOWeek (input) { 1296 var week = weekOfYear(this, 1, 4).week; 1297 return input == null ? week : this.add((input - week) * 7, 'd'); 1298 } 1299 1300 // FORMATTING 1301 1302 addFormatToken('d', 0, 'do', 'day'); 1303 1304 addFormatToken('dd', 0, 0, function (format) { 1305 return this.localeData().weekdaysMin(this, format); 1306 }); 1307 1308 addFormatToken('ddd', 0, 0, function (format) { 1309 return this.localeData().weekdaysShort(this, format); 1310 }); 1311 1312 addFormatToken('dddd', 0, 0, function (format) { 1313 return this.localeData().weekdays(this, format); 1314 }); 1315 1316 addFormatToken('e', 0, 0, 'weekday'); 1317 addFormatToken('E', 0, 0, 'isoWeekday'); 1318 1319 // ALIASES 1320 1321 addUnitAlias('day', 'd'); 1322 addUnitAlias('weekday', 'e'); 1323 addUnitAlias('isoWeekday', 'E'); 1324 1325 // PRIORITY 1326 addUnitPriority('day', 11); 1327 addUnitPriority('weekday', 11); 1328 addUnitPriority('isoWeekday', 11); 1329 1330 // PARSING 1331 1332 addRegexToken('d', match1to2); 1333 addRegexToken('e', match1to2); 1334 addRegexToken('E', match1to2); 1335 addRegexToken('dd', function (isStrict, locale) { 1336 return locale.weekdaysMinRegex(isStrict); 1337 }); 1338 addRegexToken('ddd', function (isStrict, locale) { 1339 return locale.weekdaysShortRegex(isStrict); 1340 }); 1341 addRegexToken('dddd', function (isStrict, locale) { 1342 return locale.weekdaysRegex(isStrict); 1343 }); 1344 1345 addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { 1346 var weekday = config._locale.weekdaysParse(input, token, config._strict); 1347 // if we didn't get a weekday name, mark the date as invalid 1348 if (weekday != null) { 1349 week.d = weekday; 1350 } else { 1351 getParsingFlags(config).invalidWeekday = input; 1352 } 1353 }); 1354 1355 addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { 1356 week[token] = toInt(input); 1357 }); 1358 1359 // HELPERS 1360 1361 function parseWeekday (input, locale) { 1362 if (typeof input !== 'string') { 1363 return input; 1364 } 1365 1366 if (!isNaN(input)) { 1367 return parseInt(input, 10); 1368 } 1369 1370 input = locale.weekdaysParse(input); 1371 if (typeof input === 'number') { 1372 return input; 1373 } 1374 1375 return null; 1376 } 1377 1378 function parseIsoWeekday (input, locale) { 1379 if (typeof input === 'string') { 1380 return locale.weekdaysParse(input) % 7 || 7; 1381 } 1382 return isNaN(input) ? null : input; 1383 } 1384 1385 // LOCALES 1386 function shiftWeekdays (ws, n) { 1387 return ws.slice(n, 7).concat(ws.slice(0, n)); 1388 } 1389 1390 var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); 1391 function localeWeekdays (m, format) { 1392 var weekdays = isArray(this._weekdays) ? this._weekdays : 1393 this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone']; 1394 return (m === true) ? shiftWeekdays(weekdays, this._week.dow) 1395 : (m) ? weekdays[m.day()] : weekdays; 1396 } 1397 1398 var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); 1399 function localeWeekdaysShort (m) { 1400 return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow) 1401 : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; 1402 } 1403 1404 var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); 1405 function localeWeekdaysMin (m) { 1406 return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow) 1407 : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; 1408 } 1409 1410 function handleStrictParse$1 (weekdayName, format, strict) { 1411 var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); 1412 if (!this._weekdaysParse) { 1413 this._weekdaysParse = []; 1414 this._shortWeekdaysParse = []; 1415 this._minWeekdaysParse = []; 1416 1417 for (i = 0; i < 7; ++i) { 1418 mom = createUTC([2000, 1]).day(i); 1419 this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); 1420 this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); 1421 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); 1422 } 1423 } 1424 1425 if (strict) { 1426 if (format === 'dddd') { 1427 ii = indexOf.call(this._weekdaysParse, llc); 1428 return ii !== -1 ? ii : null; 1429 } else if (format === 'ddd') { 1430 ii = indexOf.call(this._shortWeekdaysParse, llc); 1431 return ii !== -1 ? ii : null; 1432 } else { 1433 ii = indexOf.call(this._minWeekdaysParse, llc); 1434 return ii !== -1 ? ii : null; 1435 } 1436 } else { 1437 if (format === 'dddd') { 1438 ii = indexOf.call(this._weekdaysParse, llc); 1439 if (ii !== -1) { 1440 return ii; 1441 } 1442 ii = indexOf.call(this._shortWeekdaysParse, llc); 1443 if (ii !== -1) { 1444 return ii; 1445 } 1446 ii = indexOf.call(this._minWeekdaysParse, llc); 1447 return ii !== -1 ? ii : null; 1448 } else if (format === 'ddd') { 1449 ii = indexOf.call(this._shortWeekdaysParse, llc); 1450 if (ii !== -1) { 1451 return ii; 1452 } 1453 ii = indexOf.call(this._weekdaysParse, llc); 1454 if (ii !== -1) { 1455 return ii; 1456 } 1457 ii = indexOf.call(this._minWeekdaysParse, llc); 1458 return ii !== -1 ? ii : null; 1459 } else { 1460 ii = indexOf.call(this._minWeekdaysParse, llc); 1461 if (ii !== -1) { 1462 return ii; 1463 } 1464 ii = indexOf.call(this._weekdaysParse, llc); 1465 if (ii !== -1) { 1466 return ii; 1467 } 1468 ii = indexOf.call(this._shortWeekdaysParse, llc); 1469 return ii !== -1 ? ii : null; 1470 } 1471 } 1472 } 1473 1474 function localeWeekdaysParse (weekdayName, format, strict) { 1475 var i, mom, regex; 1476 1477 if (this._weekdaysParseExact) { 1478 return handleStrictParse$1.call(this, weekdayName, format, strict); 1479 } 1480 1481 if (!this._weekdaysParse) { 1482 this._weekdaysParse = []; 1483 this._minWeekdaysParse = []; 1484 this._shortWeekdaysParse = []; 1485 this._fullWeekdaysParse = []; 1486 } 1487 1488 for (i = 0; i < 7; i++) { 1489 // make the regex if we don't have it already 1490 1491 mom = createUTC([2000, 1]).day(i); 1492 if (strict && !this._fullWeekdaysParse[i]) { 1493 this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); 1494 this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); 1495 this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); 1496 } 1497 if (!this._weekdaysParse[i]) { 1498 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); 1499 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); 1500 } 1501 // test the regex 1502 if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { 1503 return i; 1504 } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { 1505 return i; 1506 } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { 1507 return i; 1508 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { 1509 return i; 1510 } 1511 } 1512 } 1513 1514 // MOMENTS 1515 1516 function getSetDayOfWeek (input) { 1517 if (!this.isValid()) { 1518 return input != null ? this : NaN; 1519 } 1520 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); 1521 if (input != null) { 1522 input = parseWeekday(input, this.localeData()); 1523 return this.add(input - day, 'd'); 1524 } else { 1525 return day; 1526 } 1527 } 1528 1529 function getSetLocaleDayOfWeek (input) { 1530 if (!this.isValid()) { 1531 return input != null ? this : NaN; 1532 } 1533 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; 1534 return input == null ? weekday : this.add(input - weekday, 'd'); 1535 } 1536 1537 function getSetISODayOfWeek (input) { 1538 if (!this.isValid()) { 1539 return input != null ? this : NaN; 1540 } 1541 1542 // behaves the same as moment#day except 1543 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) 1544 // as a setter, sunday should belong to the previous week. 1545 1546 if (input != null) { 1547 var weekday = parseIsoWeekday(input, this.localeData()); 1548 return this.day(this.day() % 7 ? weekday : weekday - 7); 1549 } else { 1550 return this.day() || 7; 1551 } 1552 } 1553 1554 var defaultWeekdaysRegex = matchWord; 1555 function weekdaysRegex (isStrict) { 1556 if (this._weekdaysParseExact) { 1557 if (!hasOwnProp(this, '_weekdaysRegex')) { 1558 computeWeekdaysParse.call(this); 1559 } 1560 if (isStrict) { 1561 return this._weekdaysStrictRegex; 1562 } else { 1563 return this._weekdaysRegex; 1564 } 1565 } else { 1566 if (!hasOwnProp(this, '_weekdaysRegex')) { 1567 this._weekdaysRegex = defaultWeekdaysRegex; 1568 } 1569 return this._weekdaysStrictRegex && isStrict ? 1570 this._weekdaysStrictRegex : this._weekdaysRegex; 1571 } 1572 } 1573 1574 var defaultWeekdaysShortRegex = matchWord; 1575 function weekdaysShortRegex (isStrict) { 1576 if (this._weekdaysParseExact) { 1577 if (!hasOwnProp(this, '_weekdaysRegex')) { 1578 computeWeekdaysParse.call(this); 1579 } 1580 if (isStrict) { 1581 return this._weekdaysShortStrictRegex; 1582 } else { 1583 return this._weekdaysShortRegex; 1584 } 1585 } else { 1586 if (!hasOwnProp(this, '_weekdaysShortRegex')) { 1587 this._weekdaysShortRegex = defaultWeekdaysShortRegex; 1588 } 1589 return this._weekdaysShortStrictRegex && isStrict ? 1590 this._weekdaysShortStrictRegex : this._weekdaysShortRegex; 1591 } 1592 } 1593 1594 var defaultWeekdaysMinRegex = matchWord; 1595 function weekdaysMinRegex (isStrict) { 1596 if (this._weekdaysParseExact) { 1597 if (!hasOwnProp(this, '_weekdaysRegex')) { 1598 computeWeekdaysParse.call(this); 1599 } 1600 if (isStrict) { 1601 return this._weekdaysMinStrictRegex; 1602 } else { 1603 return this._weekdaysMinRegex; 1604 } 1605 } else { 1606 if (!hasOwnProp(this, '_weekdaysMinRegex')) { 1607 this._weekdaysMinRegex = defaultWeekdaysMinRegex; 1608 } 1609 return this._weekdaysMinStrictRegex && isStrict ? 1610 this._weekdaysMinStrictRegex : this._weekdaysMinRegex; 1611 } 1612 } 1613 1614 1615 function computeWeekdaysParse () { 1616 function cmpLenRev (a, b) { 1617 return b.length - a.length; 1618 } 1619 1620 var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], 1621 i, mom, minp, shortp, longp; 1622 for (i = 0; i < 7; i++) { 1623 // make the regex if we don't have it already 1624 mom = createUTC([2000, 1]).day(i); 1625 minp = this.weekdaysMin(mom, ''); 1626 shortp = this.weekdaysShort(mom, ''); 1627 longp = this.weekdays(mom, ''); 1628 minPieces.push(minp); 1629 shortPieces.push(shortp); 1630 longPieces.push(longp); 1631 mixedPieces.push(minp); 1632 mixedPieces.push(shortp); 1633 mixedPieces.push(longp); 1634 } 1635 // Sorting makes sure if one weekday (or abbr) is a prefix of another it 1636 // will match the longer piece. 1637 minPieces.sort(cmpLenRev); 1638 shortPieces.sort(cmpLenRev); 1639 longPieces.sort(cmpLenRev); 1640 mixedPieces.sort(cmpLenRev); 1641 for (i = 0; i < 7; i++) { 1642 shortPieces[i] = regexEscape(shortPieces[i]); 1643 longPieces[i] = regexEscape(longPieces[i]); 1644 mixedPieces[i] = regexEscape(mixedPieces[i]); 1645 } 1646 1647 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); 1648 this._weekdaysShortRegex = this._weekdaysRegex; 1649 this._weekdaysMinRegex = this._weekdaysRegex; 1650 1651 this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); 1652 this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); 1653 this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); 1654 } 1655 1656 // FORMATTING 1657 1658 function hFormat () { 1659 return this.hours() % 12 || 12; 1660 } 1661 1662 function kFormat () { 1663 return this.hours() || 24; 1664 } 1665 1666 addFormatToken('H', ['HH', 2], 0, 'hour'); 1667 addFormatToken('h', ['hh', 2], 0, hFormat); 1668 addFormatToken('k', ['kk', 2], 0, kFormat); 1669 1670 addFormatToken('hmm', 0, 0, function () { 1671 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); 1672 }); 1673 1674 addFormatToken('hmmss', 0, 0, function () { 1675 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + 1676 zeroFill(this.seconds(), 2); 1677 }); 1678 1679 addFormatToken('Hmm', 0, 0, function () { 1680 return '' + this.hours() + zeroFill(this.minutes(), 2); 1681 }); 1682 1683 addFormatToken('Hmmss', 0, 0, function () { 1684 return '' + this.hours() + zeroFill(this.minutes(), 2) + 1685 zeroFill(this.seconds(), 2); 1686 }); 1687 1688 function meridiem (token, lowercase) { 1689 addFormatToken(token, 0, 0, function () { 1690 return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); 1691 }); 1692 } 1693 1694 meridiem('a', true); 1695 meridiem('A', false); 1696 1697 // ALIASES 1698 1699 addUnitAlias('hour', 'h'); 1700 1701 // PRIORITY 1702 addUnitPriority('hour', 13); 1703 1704 // PARSING 1705 1706 function matchMeridiem (isStrict, locale) { 1707 return locale._meridiemParse; 1708 } 1709 1710 addRegexToken('a', matchMeridiem); 1711 addRegexToken('A', matchMeridiem); 1712 addRegexToken('H', match1to2); 1713 addRegexToken('h', match1to2); 1714 addRegexToken('k', match1to2); 1715 addRegexToken('HH', match1to2, match2); 1716 addRegexToken('hh', match1to2, match2); 1717 addRegexToken('kk', match1to2, match2); 1718 1719 addRegexToken('hmm', match3to4); 1720 addRegexToken('hmmss', match5to6); 1721 addRegexToken('Hmm', match3to4); 1722 addRegexToken('Hmmss', match5to6); 1723 1724 addParseToken(['H', 'HH'], HOUR); 1725 addParseToken(['k', 'kk'], function (input, array, config) { 1726 var kInput = toInt(input); 1727 array[HOUR] = kInput === 24 ? 0 : kInput; 1728 }); 1729 addParseToken(['a', 'A'], function (input, array, config) { 1730 config._isPm = config._locale.isPM(input); 1731 config._meridiem = input; 1732 }); 1733 addParseToken(['h', 'hh'], function (input, array, config) { 1734 array[HOUR] = toInt(input); 1735 getParsingFlags(config).bigHour = true; 1736 }); 1737 addParseToken('hmm', function (input, array, config) { 1738 var pos = input.length - 2; 1739 array[HOUR] = toInt(input.substr(0, pos)); 1740 array[MINUTE] = toInt(input.substr(pos)); 1741 getParsingFlags(config).bigHour = true; 1742 }); 1743 addParseToken('hmmss', function (input, array, config) { 1744 var pos1 = input.length - 4; 1745 var pos2 = input.length - 2; 1746 array[HOUR] = toInt(input.substr(0, pos1)); 1747 array[MINUTE] = toInt(input.substr(pos1, 2)); 1748 array[SECOND] = toInt(input.substr(pos2)); 1749 getParsingFlags(config).bigHour = true; 1750 }); 1751 addParseToken('Hmm', function (input, array, config) { 1752 var pos = input.length - 2; 1753 array[HOUR] = toInt(input.substr(0, pos)); 1754 array[MINUTE] = toInt(input.substr(pos)); 1755 }); 1756 addParseToken('Hmmss', function (input, array, config) { 1757 var pos1 = input.length - 4; 1758 var pos2 = input.length - 2; 1759 array[HOUR] = toInt(input.substr(0, pos1)); 1760 array[MINUTE] = toInt(input.substr(pos1, 2)); 1761 array[SECOND] = toInt(input.substr(pos2)); 1762 }); 1763 1764 // LOCALES 1765 1766 function localeIsPM (input) { 1767 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays 1768 // Using charAt should be more compatible. 1769 return ((input + '').toLowerCase().charAt(0) === 'p'); 1770 } 1771 1772 var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; 1773 function localeMeridiem (hours, minutes, isLower) { 1774 if (hours > 11) { 1775 return isLower ? 'pm' : 'PM'; 1776 } else { 1777 return isLower ? 'am' : 'AM'; 1778 } 1779 } 1780 1781 1782 // MOMENTS 1783 1784 // Setting the hour should keep the time, because the user explicitly 1785 // specified which hour they want. So trying to maintain the same hour (in 1786 // a new timezone) makes sense. Adding/subtracting hours does not follow 1787 // this rule. 1788 var getSetHour = makeGetSet('Hours', true); 1789 1790 var baseConfig = { 1791 calendar: defaultCalendar, 1792 longDateFormat: defaultLongDateFormat, 1793 invalidDate: defaultInvalidDate, 1794 ordinal: defaultOrdinal, 1795 dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, 1796 relativeTime: defaultRelativeTime, 1797 1798 months: defaultLocaleMonths, 1799 monthsShort: defaultLocaleMonthsShort, 1800 1801 week: defaultLocaleWeek, 1802 1803 weekdays: defaultLocaleWeekdays, 1804 weekdaysMin: defaultLocaleWeekdaysMin, 1805 weekdaysShort: defaultLocaleWeekdaysShort, 1806 1807 meridiemParse: defaultLocaleMeridiemParse 1808 }; 1809 1810 // internal storage for locale config files 1811 var locales = {}; 1812 var localeFamilies = {}; 1813 var globalLocale; 1814 1815 function normalizeLocale (key) { 1816 return key ? key.toLowerCase().replace('_', '-') : key; 1817 } 1818 1819 // pick the locale from the array 1820 // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each 1821 // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root 1822 function chooseLocale (names) { 1823 var i = 0, j, next, locale, split; 1824 1825 while (i < names.length) { 1826 split = normalizeLocale(names[i]).split('-'); 1827 j = split.length; 1828 next = normalizeLocale(names[i + 1]); 1829 next = next ? next.split('-') : null; 1830 while (j > 0) { 1831 locale = loadLocale(split.slice(0, j).join('-')); 1832 if (locale) { 1833 return locale; 1834 } 1835 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { 1836 //the next array item is better than a shallower substring of this one 1837 break; 1838 } 1839 j--; 1840 } 1841 i++; 1842 } 1843 return globalLocale; 1844 } 1845 1846 function loadLocale (name) { 1847 var oldLocale = null; 1848 // TODO: Find a better way to register and load all the locales in Node 1849 if (!locales[name] && (typeof module !== 'undefined') && 1850 module && module.exports) { 1851 try { 1852 oldLocale = globalLocale._abbr; 1853 var aliasedRequire = require; 1854 aliasedRequire('./locale/' + name); 1855 getSetGlobalLocale(oldLocale); 1856 } catch (e) { } 1857 } 1858 return locales[name]; 1859 } 1860 1861 // This function will load locale and then set the global locale. If 1862 // no arguments are passed in, it will simply return the current global 1863 // locale key. 1864 function getSetGlobalLocale (key, values) { 1865 var data; 1866 if (key) { 1867 if (isUndefined(values)) { 1868 data = getLocale(key); 1869 } 1870 else { 1871 data = defineLocale(key, values); 1872 } 1873 1874 if (data) { 1875 // moment.duration._locale = moment._locale = data; 1876 globalLocale = data; 1877 } 1878 else { 1879 if ((typeof console !== 'undefined') && console.warn) { 1880 //warn user if arguments are passed but the locale could not be set 1881 console.warn('Locale ' + key + ' not found. Did you forget to load it?'); 1882 } 1883 } 1884 } 1885 1886 return globalLocale._abbr; 1887 } 1888 1889 function defineLocale (name, config) { 1890 if (config !== null) { 1891 var locale, parentConfig = baseConfig; 1892 config.abbr = name; 1893 if (locales[name] != null) { 1894 deprecateSimple('defineLocaleOverride', 1895 'use moment.updateLocale(localeName, config) to change ' + 1896 'an existing locale. moment.defineLocale(localeName, ' + 1897 'config) should only be used for creating a new locale ' + 1898 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); 1899 parentConfig = locales[name]._config; 1900 } else if (config.parentLocale != null) { 1901 if (locales[config.parentLocale] != null) { 1902 parentConfig = locales[config.parentLocale]._config; 1903 } else { 1904 locale = loadLocale(config.parentLocale); 1905 if (locale != null) { 1906 parentConfig = locale._config; 1907 } else { 1908 if (!localeFamilies[config.parentLocale]) { 1909 localeFamilies[config.parentLocale] = []; 1910 } 1911 localeFamilies[config.parentLocale].push({ 1912 name: name, 1913 config: config 1914 }); 1915 return null; 1916 } 1917 } 1918 } 1919 locales[name] = new Locale(mergeConfigs(parentConfig, config)); 1920 1921 if (localeFamilies[name]) { 1922 localeFamilies[name].forEach(function (x) { 1923 defineLocale(x.name, x.config); 1924 }); 1925 } 1926 1927 // backwards compat for now: also set the locale 1928 // make sure we set the locale AFTER all child locales have been 1929 // created, so we won't end up with the child locale set. 1930 getSetGlobalLocale(name); 1931 1932 1933 return locales[name]; 1934 } else { 1935 // useful for testing 1936 delete locales[name]; 1937 return null; 1938 } 1939 } 1940 1941 function updateLocale (name, config) { 1942 if (config != null) { 1943 var locale, tmpLocale, parentConfig = baseConfig; 1944 // MERGE 1945 tmpLocale = loadLocale(name); 1946 if (tmpLocale != null) { 1947 parentConfig = tmpLocale._config; 1948 } 1949 config = mergeConfigs(parentConfig, config); 1950 locale = new Locale(config); 1951 locale.parentLocale = locales[name]; 1952 locales[name] = locale; 1953 1954 // backwards compat for now: also set the locale 1955 getSetGlobalLocale(name); 1956 } else { 1957 // pass null for config to unupdate, useful for tests 1958 if (locales[name] != null) { 1959 if (locales[name].parentLocale != null) { 1960 locales[name] = locales[name].parentLocale; 1961 } else if (locales[name] != null) { 1962 delete locales[name]; 1963 } 1964 } 1965 } 1966 return locales[name]; 1967 } 1968 1969 // returns locale data 1970 function getLocale (key) { 1971 var locale; 1972 1973 if (key && key._locale && key._locale._abbr) { 1974 key = key._locale._abbr; 1975 } 1976 1977 if (!key) { 1978 return globalLocale; 1979 } 1980 1981 if (!isArray(key)) { 1982 //short-circuit everything else 1983 locale = loadLocale(key); 1984 if (locale) { 1985 return locale; 1986 } 1987 key = [key]; 1988 } 1989 1990 return chooseLocale(key); 1991 } 1992 1993 function listLocales () { 1994 return keys(locales); 1995 } 1996 1997 function checkOverflow (m) { 1998 var overflow; 1999 var a = m._a; 2000 2001 if (a && getParsingFlags(m).overflow === -2) { 2002 overflow = 2003 a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : 2004 a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : 2005 a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : 2006 a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : 2007 a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : 2008 a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : 2009 -1; 2010 2011 if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { 2012 overflow = DATE; 2013 } 2014 if (getParsingFlags(m)._overflowWeeks && overflow === -1) { 2015 overflow = WEEK; 2016 } 2017 if (getParsingFlags(m)._overflowWeekday && overflow === -1) { 2018 overflow = WEEKDAY; 2019 } 2020 2021 getParsingFlags(m).overflow = overflow; 2022 } 2023 2024 return m; 2025 } 2026 2027 // Pick the first defined of two or three arguments. 2028 function defaults (a, b, c) { 2029 if (a != null) { 2030 return a; 2031 } 2032 if (b != null) { 2033 return b; 2034 } 2035 return c; 2036 } 2037 2038 function currentDateArray (config) { 2039 // hooks is actually the exported moment object 2040 var nowValue = new Date(hooks.now()); 2041 if (config._useUTC) { 2042 return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; 2043 } 2044 return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; 2045 } 2046 2047 // convert an array to a date. 2048 // the array should mirror the parameters below 2049 // note: all values past the year are optional and will default to the lowest possible value. 2050 // [year, month, day , hour, minute, second, millisecond] 2051 function configFromArray (config) { 2052 var i, date, input = [], currentDate, expectedWeekday, yearToUse; 2053 2054 if (config._d) { 2055 return; 2056 } 2057 2058 currentDate = currentDateArray(config); 2059 2060 //compute day of the year from weeks and weekdays 2061 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { 2062 dayOfYearFromWeekInfo(config); 2063 } 2064 2065 //if the day of the year is set, figure out what it is 2066 if (config._dayOfYear != null) { 2067 yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); 2068 2069 if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { 2070 getParsingFlags(config)._overflowDayOfYear = true; 2071 } 2072 2073 date = createUTCDate(yearToUse, 0, config._dayOfYear); 2074 config._a[MONTH] = date.getUTCMonth(); 2075 config._a[DATE] = date.getUTCDate(); 2076 } 2077 2078 // Default to current date. 2079 // * if no year, month, day of month are given, default to today 2080 // * if day of month is given, default month and year 2081 // * if month is given, default only year 2082 // * if year is given, don't default anything 2083 for (i = 0; i < 3 && config._a[i] == null; ++i) { 2084 config._a[i] = input[i] = currentDate[i]; 2085 } 2086 2087 // Zero out whatever was not defaulted, including time 2088 for (; i < 7; i++) { 2089 config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; 2090 } 2091 2092 // Check for 24:00:00.000 2093 if (config._a[HOUR] === 24 && 2094 config._a[MINUTE] === 0 && 2095 config._a[SECOND] === 0 && 2096 config._a[MILLISECOND] === 0) { 2097 config._nextDay = true; 2098 config._a[HOUR] = 0; 2099 } 2100 2101 config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); 2102 expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); 2103 2104 // Apply timezone offset from input. The actual utcOffset can be changed 2105 // with parseZone. 2106 if (config._tzm != null) { 2107 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); 2108 } 2109 2110 if (config._nextDay) { 2111 config._a[HOUR] = 24; 2112 } 2113 2114 // check for mismatching day of week 2115 if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { 2116 getParsingFlags(config).weekdayMismatch = true; 2117 } 2118 } 2119 2120 function dayOfYearFromWeekInfo (config) { 2121 var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; 2122 2123 w = config._w; 2124 if (w.GG != null || w.W != null || w.E != null) { 2125 dow = 1; 2126 doy = 4; 2127 2128 // TODO: We need to take the current isoWeekYear, but that depends on 2129 // how we interpret now (local, utc, fixed offset). So create 2130 // a now version of current config (take local/utc/offset flags, and 2131 // create now). 2132 weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); 2133 week = defaults(w.W, 1); 2134 weekday = defaults(w.E, 1); 2135 if (weekday < 1 || weekday > 7) { 2136 weekdayOverflow = true; 2137 } 2138 } else { 2139 dow = config._locale._week.dow; 2140 doy = config._locale._week.doy; 2141 2142 var curWeek = weekOfYear(createLocal(), dow, doy); 2143 2144 weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); 2145 2146 // Default to current week. 2147 week = defaults(w.w, curWeek.week); 2148 2149 if (w.d != null) { 2150 // weekday -- low day numbers are considered next week 2151 weekday = w.d; 2152 if (weekday < 0 || weekday > 6) { 2153 weekdayOverflow = true; 2154 } 2155 } else if (w.e != null) { 2156 // local weekday -- counting starts from beginning of week 2157 weekday = w.e + dow; 2158 if (w.e < 0 || w.e > 6) { 2159 weekdayOverflow = true; 2160 } 2161 } else { 2162 // default to beginning of week 2163 weekday = dow; 2164 } 2165 } 2166 if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { 2167 getParsingFlags(config)._overflowWeeks = true; 2168 } else if (weekdayOverflow != null) { 2169 getParsingFlags(config)._overflowWeekday = true; 2170 } else { 2171 temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); 2172 config._a[YEAR] = temp.year; 2173 config._dayOfYear = temp.dayOfYear; 2174 } 2175 } 2176 2177 // iso 8601 regex 2178 // 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) 2179 var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; 2180 var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; 2181 2182 var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; 2183 2184 var isoDates = [ 2185 ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], 2186 ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], 2187 ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], 2188 ['GGGG-[W]WW', /\d{4}-W\d\d/, false], 2189 ['YYYY-DDD', /\d{4}-\d{3}/], 2190 ['YYYY-MM', /\d{4}-\d\d/, false], 2191 ['YYYYYYMMDD', /[+-]\d{10}/], 2192 ['YYYYMMDD', /\d{8}/], 2193 // YYYYMM is NOT allowed by the standard 2194 ['GGGG[W]WWE', /\d{4}W\d{3}/], 2195 ['GGGG[W]WW', /\d{4}W\d{2}/, false], 2196 ['YYYYDDD', /\d{7}/] 2197 ]; 2198 2199 // iso time formats and regexes 2200 var isoTimes = [ 2201 ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], 2202 ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], 2203 ['HH:mm:ss', /\d\d:\d\d:\d\d/], 2204 ['HH:mm', /\d\d:\d\d/], 2205 ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], 2206 ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], 2207 ['HHmmss', /\d\d\d\d\d\d/], 2208 ['HHmm', /\d\d\d\d/], 2209 ['HH', /\d\d/] 2210 ]; 2211 2212 var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; 2213 2214 // date from iso format 2215 function configFromISO (config) { 2216 var i, l, 2217 string = config._i, 2218 match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), 2219 allowTime, dateFormat, timeFormat, tzFormat; 2220 2221 if (match) { 2222 getParsingFlags(config).iso = true; 2223 2224 for (i = 0, l = isoDates.length; i < l; i++) { 2225 if (isoDates[i][1].exec(match[1])) { 2226 dateFormat = isoDates[i][0]; 2227 allowTime = isoDates[i][2] !== false; 2228 break; 2229 } 2230 } 2231 if (dateFormat == null) { 2232 config._isValid = false; 2233 return; 2234 } 2235 if (match[3]) { 2236 for (i = 0, l = isoTimes.length; i < l; i++) { 2237 if (isoTimes[i][1].exec(match[3])) { 2238 // match[2] should be 'T' or space 2239 timeFormat = (match[2] || ' ') + isoTimes[i][0]; 2240 break; 2241 } 2242 } 2243 if (timeFormat == null) { 2244 config._isValid = false; 2245 return; 2246 } 2247 } 2248 if (!allowTime && timeFormat != null) { 2249 config._isValid = false; 2250 return; 2251 } 2252 if (match[4]) { 2253 if (tzRegex.exec(match[4])) { 2254 tzFormat = 'Z'; 2255 } else { 2256 config._isValid = false; 2257 return; 2258 } 2259 } 2260 config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); 2261 configFromStringAndFormat(config); 2262 } else { 2263 config._isValid = false; 2264 } 2265 } 2266 2267 // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 2268 var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; 2269 2270 function extractFromRFC2822Strings (yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { 2271 var result = [ 2272 untruncateYear(yearStr), 2273 defaultLocaleMonthsShort.indexOf(monthStr), 2274 parseInt(dayStr, 10), 2275 parseInt(hourStr, 10), 2276 parseInt(minuteStr, 10) 2277 ]; 2278 2279 if (secondStr) { 2280 result.push(parseInt(secondStr, 10)); 2281 } 2282 2283 return result; 2284 } 2285 2286 function untruncateYear (yearStr) { 2287 var year = parseInt(yearStr, 10); 2288 if (year <= 49) { 2289 return 2000 + year; 2290 } else if (year <= 999) { 2291 return 1900 + year; 2292 } 2293 return year; 2294 } 2295 2296 function preprocessRFC2822 (s) { 2297 // Remove comments and folding whitespace and replace multiple-spaces with a single space 2298 return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); 2299 } 2300 2301 function checkWeekday (weekdayStr, parsedInput, config) { 2302 if (weekdayStr) { 2303 // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. 2304 var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), 2305 weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); 2306 if (weekdayProvided !== weekdayActual) { 2307 getParsingFlags(config).weekdayMismatch = true; 2308 config._isValid = false; 2309 return false; 2310 } 2311 } 2312 return true; 2313 } 2314 2315 var obsOffsets = { 2316 UT: 0, 2317 GMT: 0, 2318 EDT: -4 * 60, 2319 EST: -5 * 60, 2320 CDT: -5 * 60, 2321 CST: -6 * 60, 2322 MDT: -6 * 60, 2323 MST: -7 * 60, 2324 PDT: -7 * 60, 2325 PST: -8 * 60 2326 }; 2327 2328 function calculateOffset (obsOffset, militaryOffset, numOffset) { 2329 if (obsOffset) { 2330 return obsOffsets[obsOffset]; 2331 } else if (militaryOffset) { 2332 // the only allowed military tz is Z 2333 return 0; 2334 } else { 2335 var hm = parseInt(numOffset, 10); 2336 var m = hm % 100, h = (hm - m) / 100; 2337 return h * 60 + m; 2338 } 2339 } 2340 2341 // date and time from ref 2822 format 2342 function configFromRFC2822 (config) { 2343 var match = rfc2822.exec(preprocessRFC2822(config._i)); 2344 if (match) { 2345 var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); 2346 if (!checkWeekday(match[1], parsedArray, config)) { 2347 return; 2348 } 2349 2350 config._a = parsedArray; 2351 config._tzm = calculateOffset(match[8], match[9], match[10]); 2352 2353 config._d = createUTCDate.apply(null, config._a); 2354 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); 2355 2356 getParsingFlags(config).rfc2822 = true; 2357 } else { 2358 config._isValid = false; 2359 } 2360 } 2361 2362 // date from iso format or fallback 2363 function configFromString (config) { 2364 var matched = aspNetJsonRegex.exec(config._i); 2365 2366 if (matched !== null) { 2367 config._d = new Date(+matched[1]); 2368 return; 2369 } 2370 2371 configFromISO(config); 2372 if (config._isValid === false) { 2373 delete config._isValid; 2374 } else { 2375 return; 2376 } 2377 2378 configFromRFC2822(config); 2379 if (config._isValid === false) { 2380 delete config._isValid; 2381 } else { 2382 return; 2383 } 2384 2385 // Final attempt, use Input Fallback 2386 hooks.createFromInputFallback(config); 2387 } 2388 2389 hooks.createFromInputFallback = deprecate( 2390 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + 2391 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + 2392 'discouraged and will be removed in an upcoming major release. Please refer to ' + 2393 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', 2394 function (config) { 2395 config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); 2396 } 2397 ); 2398 2399 // constant that refers to the ISO standard 2400 hooks.ISO_8601 = function () { }; 2401 2402 // constant that refers to the RFC 2822 form 2403 hooks.RFC_2822 = function () { }; 2404 2405 // date from string and format string 2406 function configFromStringAndFormat (config) { 2407 // TODO: Move this to another part of the creation flow to prevent circular deps 2408 if (config._f === hooks.ISO_8601) { 2409 configFromISO(config); 2410 return; 2411 } 2412 if (config._f === hooks.RFC_2822) { 2413 configFromRFC2822(config); 2414 return; 2415 } 2416 config._a = []; 2417 getParsingFlags(config).empty = true; 2418 2419 // This array is used to make a Date, either with `new Date` or `Date.UTC` 2420 var string = '' + config._i, 2421 i, parsedInput, tokens, token, skipped, 2422 stringLength = string.length, 2423 totalParsedInputLength = 0; 2424 2425 tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; 2426 2427 for (i = 0; i < tokens.length; i++) { 2428 token = tokens[i]; 2429 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; 2430 // console.log('token', token, 'parsedInput', parsedInput, 2431 // 'regex', getParseRegexForToken(token, config)); 2432 if (parsedInput) { 2433 skipped = string.substr(0, string.indexOf(parsedInput)); 2434 if (skipped.length > 0) { 2435 getParsingFlags(config).unusedInput.push(skipped); 2436 } 2437 string = string.slice(string.indexOf(parsedInput) + parsedInput.length); 2438 totalParsedInputLength += parsedInput.length; 2439 } 2440 // don't parse if it's not a known token 2441 if (formatTokenFunctions[token]) { 2442 if (parsedInput) { 2443 getParsingFlags(config).empty = false; 2444 } 2445 else { 2446 getParsingFlags(config).unusedTokens.push(token); 2447 } 2448 addTimeToArrayFromToken(token, parsedInput, config); 2449 } 2450 else if (config._strict && !parsedInput) { 2451 getParsingFlags(config).unusedTokens.push(token); 2452 } 2453 } 2454 2455 // add remaining unparsed input length to the string 2456 getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; 2457 if (string.length > 0) { 2458 getParsingFlags(config).unusedInput.push(string); 2459 } 2460 2461 // clear _12h flag if hour is <= 12 2462 if (config._a[HOUR] <= 12 && 2463 getParsingFlags(config).bigHour === true && 2464 config._a[HOUR] > 0) { 2465 getParsingFlags(config).bigHour = undefined; 2466 } 2467 2468 getParsingFlags(config).parsedDateParts = config._a.slice(0); 2469 getParsingFlags(config).meridiem = config._meridiem; 2470 // handle meridiem 2471 config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); 2472 2473 configFromArray(config); 2474 checkOverflow(config); 2475 } 2476 2477 2478 function meridiemFixWrap (locale, hour, meridiem) { 2479 var isPm; 2480 2481 if (meridiem == null) { 2482 // nothing to do 2483 return hour; 2484 } 2485 if (locale.meridiemHour != null) { 2486 return locale.meridiemHour(hour, meridiem); 2487 } else if (locale.isPM != null) { 2488 // Fallback 2489 isPm = locale.isPM(meridiem); 2490 if (isPm && hour < 12) { 2491 hour += 12; 2492 } 2493 if (!isPm && hour === 12) { 2494 hour = 0; 2495 } 2496 return hour; 2497 } else { 2498 // this is not supposed to happen 2499 return hour; 2500 } 2501 } 2502 2503 // date from string and array of format strings 2504 function configFromStringAndArray (config) { 2505 var tempConfig, 2506 bestMoment, 2507 2508 scoreToBeat, 2509 i, 2510 currentScore; 2511 2512 if (config._f.length === 0) { 2513 getParsingFlags(config).invalidFormat = true; 2514 config._d = new Date(NaN); 2515 return; 2516 } 2517 2518 for (i = 0; i < config._f.length; i++) { 2519 currentScore = 0; 2520 tempConfig = copyConfig({}, config); 2521 if (config._useUTC != null) { 2522 tempConfig._useUTC = config._useUTC; 2523 } 2524 tempConfig._f = config._f[i]; 2525 configFromStringAndFormat(tempConfig); 2526 2527 if (!isValid(tempConfig)) { 2528 continue; 2529 } 2530 2531 // if there is any input that was not parsed add a penalty for that format 2532 currentScore += getParsingFlags(tempConfig).charsLeftOver; 2533 2534 //or tokens 2535 currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; 2536 2537 getParsingFlags(tempConfig).score = currentScore; 2538 2539 if (scoreToBeat == null || currentScore < scoreToBeat) { 2540 scoreToBeat = currentScore; 2541 bestMoment = tempConfig; 2542 } 2543 } 2544 2545 extend(config, bestMoment || tempConfig); 2546 } 2547 2548 function configFromObject (config) { 2549 if (config._d) { 2550 return; 2551 } 2552 2553 var i = normalizeObjectUnits(config._i); 2554 config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { 2555 return obj && parseInt(obj, 10); 2556 }); 2557 2558 configFromArray(config); 2559 } 2560 2561 function createFromConfig (config) { 2562 var res = new Moment(checkOverflow(prepareConfig(config))); 2563 if (res._nextDay) { 2564 // Adding is smart enough around DST 2565 res.add(1, 'd'); 2566 res._nextDay = undefined; 2567 } 2568 2569 return res; 2570 } 2571 2572 function prepareConfig (config) { 2573 var input = config._i, 2574 format = config._f; 2575 2576 config._locale = config._locale || getLocale(config._l); 2577 2578 if (input === null || (format === undefined && input === '')) { 2579 return createInvalid({ nullInput: true }); 2580 } 2581 2582 if (typeof input === 'string') { 2583 config._i = input = config._locale.preparse(input); 2584 } 2585 2586 if (isMoment(input)) { 2587 return new Moment(checkOverflow(input)); 2588 } else if (isDate(input)) { 2589 config._d = input; 2590 } else if (isArray(format)) { 2591 configFromStringAndArray(config); 2592 } else if (format) { 2593 configFromStringAndFormat(config); 2594 } else { 2595 configFromInput(config); 2596 } 2597 2598 if (!isValid(config)) { 2599 config._d = null; 2600 } 2601 2602 return config; 2603 } 2604 2605 function configFromInput (config) { 2606 var input = config._i; 2607 if (isUndefined(input)) { 2608 config._d = new Date(hooks.now()); 2609 } else if (isDate(input)) { 2610 config._d = new Date(input.valueOf()); 2611 } else if (typeof input === 'string') { 2612 configFromString(config); 2613 } else if (isArray(input)) { 2614 config._a = map(input.slice(0), function (obj) { 2615 return parseInt(obj, 10); 2616 }); 2617 configFromArray(config); 2618 } else if (isObject(input)) { 2619 configFromObject(config); 2620 } else if (isNumber(input)) { 2621 // from milliseconds 2622 config._d = new Date(input); 2623 } else { 2624 hooks.createFromInputFallback(config); 2625 } 2626 } 2627 2628 function createLocalOrUTC (input, format, locale, strict, isUTC) { 2629 var c = {}; 2630 2631 if (locale === true || locale === false) { 2632 strict = locale; 2633 locale = undefined; 2634 } 2635 2636 if ((isObject(input) && isObjectEmpty(input)) || 2637 (isArray(input) && input.length === 0)) { 2638 input = undefined; 2639 } 2640 // object construction must be done this way. 2641 // https://github.com/moment/moment/issues/1423 2642 c._isAMomentObject = true; 2643 c._useUTC = c._isUTC = isUTC; 2644 c._l = locale; 2645 c._i = input; 2646 c._f = format; 2647 c._strict = strict; 2648 2649 return createFromConfig(c); 2650 } 2651 2652 function createLocal (input, format, locale, strict) { 2653 return createLocalOrUTC(input, format, locale, strict, false); 2654 } 2655 2656 var prototypeMin = deprecate( 2657 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', 2658 function () { 2659 var other = createLocal.apply(null, arguments); 2660 if (this.isValid() && other.isValid()) { 2661 return other < this ? this : other; 2662 } else { 2663 return createInvalid(); 2664 } 2665 } 2666 ); 2667 2668 var prototypeMax = deprecate( 2669 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', 2670 function () { 2671 var other = createLocal.apply(null, arguments); 2672 if (this.isValid() && other.isValid()) { 2673 return other > this ? this : other; 2674 } else { 2675 return createInvalid(); 2676 } 2677 } 2678 ); 2679 2680 // Pick a moment m from moments so that m[fn](other) is true for all 2681 // other. This relies on the function fn to be transitive. 2682 // 2683 // moments should either be an array of moment objects or an array, whose 2684 // first element is an array of moment objects. 2685 function pickBy (fn, moments) { 2686 var res, i; 2687 if (moments.length === 1 && isArray(moments[0])) { 2688 moments = moments[0]; 2689 } 2690 if (!moments.length) { 2691 return createLocal(); 2692 } 2693 res = moments[0]; 2694 for (i = 1; i < moments.length; ++i) { 2695 if (!moments[i].isValid() || moments[i][fn](res)) { 2696 res = moments[i]; 2697 } 2698 } 2699 return res; 2700 } 2701 2702 // TODO: Use [].sort instead? 2703 function min () { 2704 var args = [].slice.call(arguments, 0); 2705 2706 return pickBy('isBefore', args); 2707 } 2708 2709 function max () { 2710 var args = [].slice.call(arguments, 0); 2711 2712 return pickBy('isAfter', args); 2713 } 2714 2715 var now = function () { 2716 return Date.now ? Date.now() : +(new Date()); 2717 }; 2718 2719 var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; 2720 2721 function isDurationValid (m) { 2722 for (var key in m) { 2723 if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { 2724 return false; 2725 } 2726 } 2727 2728 var unitHasDecimal = false; 2729 for (var i = 0; i < ordering.length; ++i) { 2730 if (m[ordering[i]]) { 2731 if (unitHasDecimal) { 2732 return false; // only allow non-integers for smallest unit 2733 } 2734 if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { 2735 unitHasDecimal = true; 2736 } 2737 } 2738 } 2739 2740 return true; 2741 } 2742 2743 function isValid$1 () { 2744 return this._isValid; 2745 } 2746 2747 function createInvalid$1 () { 2748 return createDuration(NaN); 2749 } 2750 2751 function Duration (duration) { 2752 var normalizedInput = normalizeObjectUnits(duration), 2753 years = normalizedInput.year || 0, 2754 quarters = normalizedInput.quarter || 0, 2755 months = normalizedInput.month || 0, 2756 weeks = normalizedInput.week || normalizedInput.isoWeek || 0, 2757 days = normalizedInput.day || 0, 2758 hours = normalizedInput.hour || 0, 2759 minutes = normalizedInput.minute || 0, 2760 seconds = normalizedInput.second || 0, 2761 milliseconds = normalizedInput.millisecond || 0; 2762 2763 this._isValid = isDurationValid(normalizedInput); 2764 2765 // representation for dateAddRemove 2766 this._milliseconds = +milliseconds + 2767 seconds * 1e3 + // 1000 2768 minutes * 6e4 + // 1000 * 60 2769 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 2770 // Because of dateAddRemove treats 24 hours as different from a 2771 // day when working around DST, we need to store them separately 2772 this._days = +days + 2773 weeks * 7; 2774 // It is impossible to translate months into days without knowing 2775 // which months you are are talking about, so we have to store 2776 // it separately. 2777 this._months = +months + 2778 quarters * 3 + 2779 years * 12; 2780 2781 this._data = {}; 2782 2783 this._locale = getLocale(); 2784 2785 this._bubble(); 2786 } 2787 2788 function isDuration (obj) { 2789 return obj instanceof Duration; 2790 } 2791 2792 function absRound (number) { 2793 if (number < 0) { 2794 return Math.round(-1 * number) * -1; 2795 } else { 2796 return Math.round(number); 2797 } 2798 } 2799 2800 // FORMATTING 2801 2802 function offset (token, separator) { 2803 addFormatToken(token, 0, 0, function () { 2804 var offset = this.utcOffset(); 2805 var sign = '+'; 2806 if (offset < 0) { 2807 offset = -offset; 2808 sign = '-'; 2809 } 2810 return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); 2811 }); 2812 } 2813 2814 offset('Z', ':'); 2815 offset('ZZ', ''); 2816 2817 // PARSING 2818 2819 addRegexToken('Z', matchShortOffset); 2820 addRegexToken('ZZ', matchShortOffset); 2821 addParseToken(['Z', 'ZZ'], function (input, array, config) { 2822 config._useUTC = true; 2823 config._tzm = offsetFromString(matchShortOffset, input); 2824 }); 2825 2826 // HELPERS 2827 2828 // timezone chunker 2829 // '+10:00' > ['10', '00'] 2830 // '-1530' > ['-15', '30'] 2831 var chunkOffset = /([\+\-]|\d\d)/gi; 2832 2833 function offsetFromString (matcher, string) { 2834 var matches = (string || '').match(matcher); 2835 2836 if (matches === null) { 2837 return null; 2838 } 2839 2840 var chunk = matches[matches.length - 1] || []; 2841 var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; 2842 var minutes = +(parts[1] * 60) + toInt(parts[2]); 2843 2844 return minutes === 0 ? 2845 0 : 2846 parts[0] === '+' ? minutes : -minutes; 2847 } 2848 2849 // Return a moment from input, that is local/utc/zone equivalent to model. 2850 function cloneWithOffset (input, model) { 2851 var res, diff; 2852 if (model._isUTC) { 2853 res = model.clone(); 2854 diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); 2855 // Use low-level api, because this fn is low-level api. 2856 res._d.setTime(res._d.valueOf() + diff); 2857 hooks.updateOffset(res, false); 2858 return res; 2859 } else { 2860 return createLocal(input).local(); 2861 } 2862 } 2863 2864 function getDateOffset (m) { 2865 // On Firefox.24 Date#getTimezoneOffset returns a floating point. 2866 // https://github.com/moment/moment/pull/1871 2867 return -Math.round(m._d.getTimezoneOffset() / 15) * 15; 2868 } 2869 2870 // HOOKS 2871 2872 // This function will be called whenever a moment is mutated. 2873 // It is intended to keep the offset in sync with the timezone. 2874 hooks.updateOffset = function () { }; 2875 2876 // MOMENTS 2877 2878 // keepLocalTime = true means only change the timezone, without 2879 // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> 2880 // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset 2881 // +0200, so we adjust the time as needed, to be valid. 2882 // 2883 // Keeping the time actually adds/subtracts (one hour) 2884 // from the actual represented time. That is why we call updateOffset 2885 // a second time. In case it wants us to change the offset again 2886 // _changeInProgress == true case, then we have to adjust, because 2887 // there is no such time in the given timezone. 2888 function getSetOffset (input, keepLocalTime, keepMinutes) { 2889 var offset = this._offset || 0, 2890 localAdjust; 2891 if (!this.isValid()) { 2892 return input != null ? this : NaN; 2893 } 2894 if (input != null) { 2895 if (typeof input === 'string') { 2896 input = offsetFromString(matchShortOffset, input); 2897 if (input === null) { 2898 return this; 2899 } 2900 } else if (Math.abs(input) < 16 && !keepMinutes) { 2901 input = input * 60; 2902 } 2903 if (!this._isUTC && keepLocalTime) { 2904 localAdjust = getDateOffset(this); 2905 } 2906 this._offset = input; 2907 this._isUTC = true; 2908 if (localAdjust != null) { 2909 this.add(localAdjust, 'm'); 2910 } 2911 if (offset !== input) { 2912 if (!keepLocalTime || this._changeInProgress) { 2913 addSubtract(this, createDuration(input - offset, 'm'), 1, false); 2914 } else if (!this._changeInProgress) { 2915 this._changeInProgress = true; 2916 hooks.updateOffset(this, true); 2917 this._changeInProgress = null; 2918 } 2919 } 2920 return this; 2921 } else { 2922 return this._isUTC ? offset : getDateOffset(this); 2923 } 2924 } 2925 2926 function getSetZone (input, keepLocalTime) { 2927 if (input != null) { 2928 if (typeof input !== 'string') { 2929 input = -input; 2930 } 2931 2932 this.utcOffset(input, keepLocalTime); 2933 2934 return this; 2935 } else { 2936 return -this.utcOffset(); 2937 } 2938 } 2939 2940 function setOffsetToUTC (keepLocalTime) { 2941 return this.utcOffset(0, keepLocalTime); 2942 } 2943 2944 function setOffsetToLocal (keepLocalTime) { 2945 if (this._isUTC) { 2946 this.utcOffset(0, keepLocalTime); 2947 this._isUTC = false; 2948 2949 if (keepLocalTime) { 2950 this.subtract(getDateOffset(this), 'm'); 2951 } 2952 } 2953 return this; 2954 } 2955 2956 function setOffsetToParsedOffset () { 2957 if (this._tzm != null) { 2958 this.utcOffset(this._tzm, false, true); 2959 } else if (typeof this._i === 'string') { 2960 var tZone = offsetFromString(matchOffset, this._i); 2961 if (tZone != null) { 2962 this.utcOffset(tZone); 2963 } 2964 else { 2965 this.utcOffset(0, true); 2966 } 2967 } 2968 return this; 2969 } 2970 2971 function hasAlignedHourOffset (input) { 2972 if (!this.isValid()) { 2973 return false; 2974 } 2975 input = input ? createLocal(input).utcOffset() : 0; 2976 2977 return (this.utcOffset() - input) % 60 === 0; 2978 } 2979 2980 function isDaylightSavingTime () { 2981 return ( 2982 this.utcOffset() > this.clone().month(0).utcOffset() || 2983 this.utcOffset() > this.clone().month(5).utcOffset() 2984 ); 2985 } 2986 2987 function isDaylightSavingTimeShifted () { 2988 if (!isUndefined(this._isDSTShifted)) { 2989 return this._isDSTShifted; 2990 } 2991 2992 var c = {}; 2993 2994 copyConfig(c, this); 2995 c = prepareConfig(c); 2996 2997 if (c._a) { 2998 var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); 2999 this._isDSTShifted = this.isValid() && 3000 compareArrays(c._a, other.toArray()) > 0; 3001 } else { 3002 this._isDSTShifted = false; 3003 } 3004 3005 return this._isDSTShifted; 3006 } 3007 3008 function isLocal () { 3009 return this.isValid() ? !this._isUTC : false; 3010 } 3011 3012 function isUtcOffset () { 3013 return this.isValid() ? this._isUTC : false; 3014 } 3015 3016 function isUtc () { 3017 return this.isValid() ? this._isUTC && this._offset === 0 : false; 3018 } 3019 3020 // ASP.NET json date format regex 3021 var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; 3022 3023 // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html 3024 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere 3025 // and further modified to allow for strings containing both week and day 3026 var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; 3027 3028 function createDuration (input, key) { 3029 var duration = input, 3030 // matching against regexp is expensive, do it on demand 3031 match = null, 3032 sign, 3033 ret, 3034 diffRes; 3035 3036 if (isDuration(input)) { 3037 duration = { 3038 ms: input._milliseconds, 3039 d: input._days, 3040 M: input._months 3041 }; 3042 } else if (isNumber(input)) { 3043 duration = {}; 3044 if (key) { 3045 duration[key] = input; 3046 } else { 3047 duration.milliseconds = input; 3048 } 3049 } else if (!!(match = aspNetRegex.exec(input))) { 3050 sign = (match[1] === '-') ? -1 : 1; 3051 duration = { 3052 y: 0, 3053 d: toInt(match[DATE]) * sign, 3054 h: toInt(match[HOUR]) * sign, 3055 m: toInt(match[MINUTE]) * sign, 3056 s: toInt(match[SECOND]) * sign, 3057 ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match 3058 }; 3059 } else if (!!(match = isoRegex.exec(input))) { 3060 sign = (match[1] === '-') ? -1 : 1; 3061 duration = { 3062 y: parseIso(match[2], sign), 3063 M: parseIso(match[3], sign), 3064 w: parseIso(match[4], sign), 3065 d: parseIso(match[5], sign), 3066 h: parseIso(match[6], sign), 3067 m: parseIso(match[7], sign), 3068 s: parseIso(match[8], sign) 3069 }; 3070 } else if (duration == null) {// checks for null or undefined 3071 duration = {}; 3072 } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { 3073 diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); 3074 3075 duration = {}; 3076 duration.ms = diffRes.milliseconds; 3077 duration.M = diffRes.months; 3078 } 3079 3080 ret = new Duration(duration); 3081 3082 if (isDuration(input) && hasOwnProp(input, '_locale')) { 3083 ret._locale = input._locale; 3084 } 3085 3086 return ret; 3087 } 3088 3089 createDuration.fn = Duration.prototype; 3090 createDuration.invalid = createInvalid$1; 3091 3092 function parseIso (inp, sign) { 3093 // We'd normally use ~~inp for this, but unfortunately it also 3094 // converts floats to ints. 3095 // inp may be undefined, so careful calling replace on it. 3096 var res = inp && parseFloat(inp.replace(',', '.')); 3097 // apply sign while we're at it 3098 return (isNaN(res) ? 0 : res) * sign; 3099 } 3100 3101 function positiveMomentsDifference (base, other) { 3102 var res = {}; 3103 3104 res.months = other.month() - base.month() + 3105 (other.year() - base.year()) * 12; 3106 if (base.clone().add(res.months, 'M').isAfter(other)) { 3107 --res.months; 3108 } 3109 3110 res.milliseconds = +other - +(base.clone().add(res.months, 'M')); 3111 3112 return res; 3113 } 3114 3115 function momentsDifference (base, other) { 3116 var res; 3117 if (!(base.isValid() && other.isValid())) { 3118 return { milliseconds: 0, months: 0 }; 3119 } 3120 3121 other = cloneWithOffset(other, base); 3122 if (base.isBefore(other)) { 3123 res = positiveMomentsDifference(base, other); 3124 } else { 3125 res = positiveMomentsDifference(other, base); 3126 res.milliseconds = -res.milliseconds; 3127 res.months = -res.months; 3128 } 3129 3130 return res; 3131 } 3132 3133 // TODO: remove 'name' arg after deprecation is removed 3134 function createAdder (direction, name) { 3135 return function (val, period) { 3136 var dur, tmp; 3137 //invert the arguments, but complain about it 3138 if (period !== null && !isNaN(+period)) { 3139 deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + 3140 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); 3141 tmp = val; val = period; period = tmp; 3142 } 3143 3144 val = typeof val === 'string' ? +val : val; 3145 dur = createDuration(val, period); 3146 addSubtract(this, dur, direction); 3147 return this; 3148 }; 3149 } 3150 3151 function addSubtract (mom, duration, isAdding, updateOffset) { 3152 var milliseconds = duration._milliseconds, 3153 days = absRound(duration._days), 3154 months = absRound(duration._months); 3155 3156 if (!mom.isValid()) { 3157 // No op 3158 return; 3159 } 3160 3161 updateOffset = updateOffset == null ? true : updateOffset; 3162 3163 if (months) { 3164 setMonth(mom, get(mom, 'Month') + months * isAdding); 3165 } 3166 if (days) { 3167 set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); 3168 } 3169 if (milliseconds) { 3170 mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); 3171 } 3172 if (updateOffset) { 3173 hooks.updateOffset(mom, days || months); 3174 } 3175 } 3176 3177 var add = createAdder(1, 'add'); 3178 var subtract = createAdder(-1, 'subtract'); 3179 3180 function getCalendarFormat (myMoment, now) { 3181 var diff = myMoment.diff(now, 'days', true); 3182 return diff < -6 ? 'sameElse' : 3183 diff < -1 ? 'lastWeek' : 3184 diff < 0 ? 'lastDay' : 3185 diff < 1 ? 'sameDay' : 3186 diff < 2 ? 'nextDay' : 3187 diff < 7 ? 'nextWeek' : 'sameElse'; 3188 } 3189 3190 function calendar$1 (time, formats) { 3191 // We want to compare the start of today, vs this. 3192 // Getting start-of-today depends on whether we're local/utc/offset or not. 3193 var now = time || createLocal(), 3194 sod = cloneWithOffset(now, this).startOf('day'), 3195 format = hooks.calendarFormat(this, sod) || 'sameElse'; 3196 3197 var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); 3198 3199 return this.format(output || this.localeData().calendar(format, this, createLocal(now))); 3200 } 3201 3202 function clone () { 3203 return new Moment(this); 3204 } 3205 3206 function isAfter (input, units) { 3207 var localInput = isMoment(input) ? input : createLocal(input); 3208 if (!(this.isValid() && localInput.isValid())) { 3209 return false; 3210 } 3211 units = normalizeUnits(units) || 'millisecond'; 3212 if (units === 'millisecond') { 3213 return this.valueOf() > localInput.valueOf(); 3214 } else { 3215 return localInput.valueOf() < this.clone().startOf(units).valueOf(); 3216 } 3217 } 3218 3219 function isBefore (input, units) { 3220 var localInput = isMoment(input) ? input : createLocal(input); 3221 if (!(this.isValid() && localInput.isValid())) { 3222 return false; 3223 } 3224 units = normalizeUnits(units) || 'millisecond'; 3225 if (units === 'millisecond') { 3226 return this.valueOf() < localInput.valueOf(); 3227 } else { 3228 return this.clone().endOf(units).valueOf() < localInput.valueOf(); 3229 } 3230 } 3231 3232 function isBetween (from, to, units, inclusivity) { 3233 var localFrom = isMoment(from) ? from : createLocal(from), 3234 localTo = isMoment(to) ? to : createLocal(to); 3235 if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { 3236 return false; 3237 } 3238 inclusivity = inclusivity || '()'; 3239 return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && 3240 (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units)); 3241 } 3242 3243 function isSame (input, units) { 3244 var localInput = isMoment(input) ? input : createLocal(input), 3245 inputMs; 3246 if (!(this.isValid() && localInput.isValid())) { 3247 return false; 3248 } 3249 units = normalizeUnits(units) || 'millisecond'; 3250 if (units === 'millisecond') { 3251 return this.valueOf() === localInput.valueOf(); 3252 } else { 3253 inputMs = localInput.valueOf(); 3254 return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); 3255 } 3256 } 3257 3258 function isSameOrAfter (input, units) { 3259 return this.isSame(input, units) || this.isAfter(input, units); 3260 } 3261 3262 function isSameOrBefore (input, units) { 3263 return this.isSame(input, units) || this.isBefore(input, units); 3264 } 3265 3266 function diff (input, units, asFloat) { 3267 var that, 3268 zoneDelta, 3269 output; 3270 3271 if (!this.isValid()) { 3272 return NaN; 3273 } 3274 3275 that = cloneWithOffset(input, this); 3276 3277 if (!that.isValid()) { 3278 return NaN; 3279 } 3280 3281 zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; 3282 3283 units = normalizeUnits(units); 3284 3285 switch (units) { 3286 case 'year': output = monthDiff(this, that) / 12; break; 3287 case 'month': output = monthDiff(this, that); break; 3288 case 'quarter': output = monthDiff(this, that) / 3; break; 3289 case 'second': output = (this - that) / 1e3; break; // 1000 3290 case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 3291 case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 3292 case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst 3293 case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst 3294 default: output = this - that; 3295 } 3296 3297 return asFloat ? output : absFloor(output); 3298 } 3299 3300 function monthDiff (a, b) { 3301 // difference in months 3302 var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), 3303 // b is in (anchor - 1 month, anchor + 1 month) 3304 anchor = a.clone().add(wholeMonthDiff, 'months'), 3305 anchor2, adjust; 3306 3307 if (b - anchor < 0) { 3308 anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); 3309 // linear across the month 3310 adjust = (b - anchor) / (anchor - anchor2); 3311 } else { 3312 anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); 3313 // linear across the month 3314 adjust = (b - anchor) / (anchor2 - anchor); 3315 } 3316 3317 //check for negative zero, return zero if negative zero 3318 return -(wholeMonthDiff + adjust) || 0; 3319 } 3320 3321 hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; 3322 hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; 3323 3324 function toString () { 3325 return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); 3326 } 3327 3328 function toISOString (keepOffset) { 3329 if (!this.isValid()) { 3330 return null; 3331 } 3332 var utc = keepOffset !== true; 3333 var m = utc ? this.clone().utc() : this; 3334 if (m.year() < 0 || m.year() > 9999) { 3335 return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); 3336 } 3337 if (isFunction(Date.prototype.toISOString)) { 3338 // native implementation is ~50x faster, use it when we can 3339 if (utc) { 3340 return this.toDate().toISOString(); 3341 } else { 3342 return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); 3343 } 3344 } 3345 return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); 3346 } 3347 3348 /** 3349 * Return a human readable representation of a moment that can 3350 * also be evaluated to get a new moment which is the same 3351 * 3352 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects 3353 */ 3354 function inspect () { 3355 if (!this.isValid()) { 3356 return 'moment.invalid(/* ' + this._i + ' */)'; 3357 } 3358 var func = 'moment'; 3359 var zone = ''; 3360 if (!this.isLocal()) { 3361 func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; 3362 zone = 'Z'; 3363 } 3364 var prefix = '[' + func + '("]'; 3365 var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; 3366 var datetime = '-MM-DD[T]HH:mm:ss.SSS'; 3367 var suffix = zone + '[")]'; 3368 3369 return this.format(prefix + year + datetime + suffix); 3370 } 3371 3372 function format (inputString) { 3373 if (!inputString) { 3374 inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; 3375 } 3376 var output = formatMoment(this, inputString); 3377 return this.localeData().postformat(output); 3378 } 3379 3380 function from (time, withoutSuffix) { 3381 if (this.isValid() && 3382 ((isMoment(time) && time.isValid()) || 3383 createLocal(time).isValid())) { 3384 return createDuration({ to: this, from: time }).locale(this.locale()).humanize(!withoutSuffix); 3385 } else { 3386 return this.localeData().invalidDate(); 3387 } 3388 } 3389 3390 function fromNow (withoutSuffix) { 3391 return this.from(createLocal(), withoutSuffix); 3392 } 3393 3394 function to (time, withoutSuffix) { 3395 if (this.isValid() && 3396 ((isMoment(time) && time.isValid()) || 3397 createLocal(time).isValid())) { 3398 return createDuration({ from: this, to: time }).locale(this.locale()).humanize(!withoutSuffix); 3399 } else { 3400 return this.localeData().invalidDate(); 3401 } 3402 } 3403 3404 function toNow (withoutSuffix) { 3405 return this.to(createLocal(), withoutSuffix); 3406 } 3407 3408 // If passed a locale key, it will set the locale for this 3409 // instance. Otherwise, it will return the locale configuration 3410 // variables for this instance. 3411 function locale (key) { 3412 var newLocaleData; 3413 3414 if (key === undefined) { 3415 return this._locale._abbr; 3416 } else { 3417 newLocaleData = getLocale(key); 3418 if (newLocaleData != null) { 3419 this._locale = newLocaleData; 3420 } 3421 return this; 3422 } 3423 } 3424 3425 var lang = deprecate( 3426 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', 3427 function (key) { 3428 if (key === undefined) { 3429 return this.localeData(); 3430 } else { 3431 return this.locale(key); 3432 } 3433 } 3434 ); 3435 3436 function localeData () { 3437 return this._locale; 3438 } 3439 3440 var MS_PER_SECOND = 1000; 3441 var MS_PER_MINUTE = 60 * MS_PER_SECOND; 3442 var MS_PER_HOUR = 60 * MS_PER_MINUTE; 3443 var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; 3444 3445 // actual modulo - handles negative numbers (for dates before 1970): 3446 function mod$1 (dividend, divisor) { 3447 return (dividend % divisor + divisor) % divisor; 3448 } 3449 3450 function localStartOfDate (y, m, d) { 3451 // the date constructor remaps years 0-99 to 1900-1999 3452 if (y < 100 && y >= 0) { 3453 // preserve leap years using a full 400 year cycle, then reset 3454 return new Date(y + 400, m, d) - MS_PER_400_YEARS; 3455 } else { 3456 return new Date(y, m, d).valueOf(); 3457 } 3458 } 3459 3460 function utcStartOfDate (y, m, d) { 3461 // Date.UTC remaps years 0-99 to 1900-1999 3462 if (y < 100 && y >= 0) { 3463 // preserve leap years using a full 400 year cycle, then reset 3464 return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS; 3465 } else { 3466 return Date.UTC(y, m, d); 3467 } 3468 } 3469 3470 function startOf (units) { 3471 var time; 3472 units = normalizeUnits(units); 3473 if (units === undefined || units === 'millisecond' || !this.isValid()) { 3474 return this; 3475 } 3476 3477 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; 3478 3479 switch (units) { 3480 case 'year': 3481 time = startOfDate(this.year(), 0, 1); 3482 break; 3483 case 'quarter': 3484 time = startOfDate(this.year(), this.month() - this.month() % 3, 1); 3485 break; 3486 case 'month': 3487 time = startOfDate(this.year(), this.month(), 1); 3488 break; 3489 case 'week': 3490 time = startOfDate(this.year(), this.month(), this.date() - this.weekday()); 3491 break; 3492 case 'isoWeek': 3493 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1)); 3494 break; 3495 case 'day': 3496 case 'date': 3497 time = startOfDate(this.year(), this.month(), this.date()); 3498 break; 3499 case 'hour': 3500 time = this._d.valueOf(); 3501 time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR); 3502 break; 3503 case 'minute': 3504 time = this._d.valueOf(); 3505 time -= mod$1(time, MS_PER_MINUTE); 3506 break; 3507 case 'second': 3508 time = this._d.valueOf(); 3509 time -= mod$1(time, MS_PER_SECOND); 3510 break; 3511 } 3512 3513 this._d.setTime(time); 3514 hooks.updateOffset(this, true); 3515 return this; 3516 } 3517 3518 function endOf (units) { 3519 var time; 3520 units = normalizeUnits(units); 3521 if (units === undefined || units === 'millisecond' || !this.isValid()) { 3522 return this; 3523 } 3524 3525 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; 3526 3527 switch (units) { 3528 case 'year': 3529 time = startOfDate(this.year() + 1, 0, 1) - 1; 3530 break; 3531 case 'quarter': 3532 time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1; 3533 break; 3534 case 'month': 3535 time = startOfDate(this.year(), this.month() + 1, 1) - 1; 3536 break; 3537 case 'week': 3538 time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1; 3539 break; 3540 case 'isoWeek': 3541 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1; 3542 break; 3543 case 'day': 3544 case 'date': 3545 time = startOfDate(this.year(), this.month(), this.date() + 1) - 1; 3546 break; 3547 case 'hour': 3548 time = this._d.valueOf(); 3549 time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1; 3550 break; 3551 case 'minute': 3552 time = this._d.valueOf(); 3553 time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1; 3554 break; 3555 case 'second': 3556 time = this._d.valueOf(); 3557 time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1; 3558 break; 3559 } 3560 3561 this._d.setTime(time); 3562 hooks.updateOffset(this, true); 3563 return this; 3564 } 3565 3566 function valueOf () { 3567 return this._d.valueOf() - ((this._offset || 0) * 60000); 3568 } 3569 3570 function unix () { 3571 return Math.floor(this.valueOf() / 1000); 3572 } 3573 3574 function toDate () { 3575 return new Date(this.valueOf()); 3576 } 3577 3578 function toArray () { 3579 var m = this; 3580 return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; 3581 } 3582 3583 function toObject () { 3584 var m = this; 3585 return { 3586 years: m.year(), 3587 months: m.month(), 3588 date: m.date(), 3589 hours: m.hours(), 3590 minutes: m.minutes(), 3591 seconds: m.seconds(), 3592 milliseconds: m.milliseconds() 3593 }; 3594 } 3595 3596 function toJSON () { 3597 // new Date(NaN).toJSON() === null 3598 return this.isValid() ? this.toISOString() : null; 3599 } 3600 3601 function isValid$2 () { 3602 return isValid(this); 3603 } 3604 3605 function parsingFlags () { 3606 return extend({}, getParsingFlags(this)); 3607 } 3608 3609 function invalidAt () { 3610 return getParsingFlags(this).overflow; 3611 } 3612 3613 function creationData () { 3614 return { 3615 input: this._i, 3616 format: this._f, 3617 locale: this._locale, 3618 isUTC: this._isUTC, 3619 strict: this._strict 3620 }; 3621 } 3622 3623 // FORMATTING 3624 3625 addFormatToken(0, ['gg', 2], 0, function () { 3626 return this.weekYear() % 100; 3627 }); 3628 3629 addFormatToken(0, ['GG', 2], 0, function () { 3630 return this.isoWeekYear() % 100; 3631 }); 3632 3633 function addWeekYearFormatToken (token, getter) { 3634 addFormatToken(0, [token, token.length], 0, getter); 3635 } 3636 3637 addWeekYearFormatToken('gggg', 'weekYear'); 3638 addWeekYearFormatToken('ggggg', 'weekYear'); 3639 addWeekYearFormatToken('GGGG', 'isoWeekYear'); 3640 addWeekYearFormatToken('GGGGG', 'isoWeekYear'); 3641 3642 // ALIASES 3643 3644 addUnitAlias('weekYear', 'gg'); 3645 addUnitAlias('isoWeekYear', 'GG'); 3646 3647 // PRIORITY 3648 3649 addUnitPriority('weekYear', 1); 3650 addUnitPriority('isoWeekYear', 1); 3651 3652 3653 // PARSING 3654 3655 addRegexToken('G', matchSigned); 3656 addRegexToken('g', matchSigned); 3657 addRegexToken('GG', match1to2, match2); 3658 addRegexToken('gg', match1to2, match2); 3659 addRegexToken('GGGG', match1to4, match4); 3660 addRegexToken('gggg', match1to4, match4); 3661 addRegexToken('GGGGG', match1to6, match6); 3662 addRegexToken('ggggg', match1to6, match6); 3663 3664 addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { 3665 week[token.substr(0, 2)] = toInt(input); 3666 }); 3667 3668 addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { 3669 week[token] = hooks.parseTwoDigitYear(input); 3670 }); 3671 3672 // MOMENTS 3673 3674 function getSetWeekYear (input) { 3675 return getSetWeekYearHelper.call(this, 3676 input, 3677 this.week(), 3678 this.weekday(), 3679 this.localeData()._week.dow, 3680 this.localeData()._week.doy); 3681 } 3682 3683 function getSetISOWeekYear (input) { 3684 return getSetWeekYearHelper.call(this, 3685 input, this.isoWeek(), this.isoWeekday(), 1, 4); 3686 } 3687 3688 function getISOWeeksInYear () { 3689 return weeksInYear(this.year(), 1, 4); 3690 } 3691 3692 function getWeeksInYear () { 3693 var weekInfo = this.localeData()._week; 3694 return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); 3695 } 3696 3697 function getSetWeekYearHelper (input, week, weekday, dow, doy) { 3698 var weeksTarget; 3699 if (input == null) { 3700 return weekOfYear(this, dow, doy).year; 3701 } else { 3702 weeksTarget = weeksInYear(input, dow, doy); 3703 if (week > weeksTarget) { 3704 week = weeksTarget; 3705 } 3706 return setWeekAll.call(this, input, week, weekday, dow, doy); 3707 } 3708 } 3709 3710 function setWeekAll (weekYear, week, weekday, dow, doy) { 3711 var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), 3712 date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); 3713 3714 this.year(date.getUTCFullYear()); 3715 this.month(date.getUTCMonth()); 3716 this.date(date.getUTCDate()); 3717 return this; 3718 } 3719 3720 // FORMATTING 3721 3722 addFormatToken('Q', 0, 'Qo', 'quarter'); 3723 3724 // ALIASES 3725 3726 addUnitAlias('quarter', 'Q'); 3727 3728 // PRIORITY 3729 3730 addUnitPriority('quarter', 7); 3731 3732 // PARSING 3733 3734 addRegexToken('Q', match1); 3735 addParseToken('Q', function (input, array) { 3736 array[MONTH] = (toInt(input) - 1) * 3; 3737 }); 3738 3739 // MOMENTS 3740 3741 function getSetQuarter (input) { 3742 return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); 3743 } 3744 3745 // FORMATTING 3746 3747 addFormatToken('D', ['DD', 2], 'Do', 'date'); 3748 3749 // ALIASES 3750 3751 addUnitAlias('date', 'D'); 3752 3753 // PRIORITY 3754 addUnitPriority('date', 9); 3755 3756 // PARSING 3757 3758 addRegexToken('D', match1to2); 3759 addRegexToken('DD', match1to2, match2); 3760 addRegexToken('Do', function (isStrict, locale) { 3761 // TODO: Remove "ordinalParse" fallback in next major release. 3762 return isStrict ? 3763 (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : 3764 locale._dayOfMonthOrdinalParseLenient; 3765 }); 3766 3767 addParseToken(['D', 'DD'], DATE); 3768 addParseToken('Do', function (input, array) { 3769 array[DATE] = toInt(input.match(match1to2)[0]); 3770 }); 3771 3772 // MOMENTS 3773 3774 var getSetDayOfMonth = makeGetSet('Date', true); 3775 3776 // FORMATTING 3777 3778 addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); 3779 3780 // ALIASES 3781 3782 addUnitAlias('dayOfYear', 'DDD'); 3783 3784 // PRIORITY 3785 addUnitPriority('dayOfYear', 4); 3786 3787 // PARSING 3788 3789 addRegexToken('DDD', match1to3); 3790 addRegexToken('DDDD', match3); 3791 addParseToken(['DDD', 'DDDD'], function (input, array, config) { 3792 config._dayOfYear = toInt(input); 3793 }); 3794 3795 // HELPERS 3796 3797 // MOMENTS 3798 3799 function getSetDayOfYear (input) { 3800 var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; 3801 return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); 3802 } 3803 3804 // FORMATTING 3805 3806 addFormatToken('m', ['mm', 2], 0, 'minute'); 3807 3808 // ALIASES 3809 3810 addUnitAlias('minute', 'm'); 3811 3812 // PRIORITY 3813 3814 addUnitPriority('minute', 14); 3815 3816 // PARSING 3817 3818 addRegexToken('m', match1to2); 3819 addRegexToken('mm', match1to2, match2); 3820 addParseToken(['m', 'mm'], MINUTE); 3821 3822 // MOMENTS 3823 3824 var getSetMinute = makeGetSet('Minutes', false); 3825 3826 // FORMATTING 3827 3828 addFormatToken('s', ['ss', 2], 0, 'second'); 3829 3830 // ALIASES 3831 3832 addUnitAlias('second', 's'); 3833 3834 // PRIORITY 3835 3836 addUnitPriority('second', 15); 3837 3838 // PARSING 3839 3840 addRegexToken('s', match1to2); 3841 addRegexToken('ss', match1to2, match2); 3842 addParseToken(['s', 'ss'], SECOND); 3843 3844 // MOMENTS 3845 3846 var getSetSecond = makeGetSet('Seconds', false); 3847 3848 // FORMATTING 3849 3850 addFormatToken('S', 0, 0, function () { 3851 return ~~(this.millisecond() / 100); 3852 }); 3853 3854 addFormatToken(0, ['SS', 2], 0, function () { 3855 return ~~(this.millisecond() / 10); 3856 }); 3857 3858 addFormatToken(0, ['SSS', 3], 0, 'millisecond'); 3859 addFormatToken(0, ['SSSS', 4], 0, function () { 3860 return this.millisecond() * 10; 3861 }); 3862 addFormatToken(0, ['SSSSS', 5], 0, function () { 3863 return this.millisecond() * 100; 3864 }); 3865 addFormatToken(0, ['SSSSSS', 6], 0, function () { 3866 return this.millisecond() * 1000; 3867 }); 3868 addFormatToken(0, ['SSSSSSS', 7], 0, function () { 3869 return this.millisecond() * 10000; 3870 }); 3871 addFormatToken(0, ['SSSSSSSS', 8], 0, function () { 3872 return this.millisecond() * 100000; 3873 }); 3874 addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { 3875 return this.millisecond() * 1000000; 3876 }); 3877 3878 3879 // ALIASES 3880 3881 addUnitAlias('millisecond', 'ms'); 3882 3883 // PRIORITY 3884 3885 addUnitPriority('millisecond', 16); 3886 3887 // PARSING 3888 3889 addRegexToken('S', match1to3, match1); 3890 addRegexToken('SS', match1to3, match2); 3891 addRegexToken('SSS', match1to3, match3); 3892 3893 var token; 3894 for (token = 'SSSS'; token.length <= 9; token += 'S') { 3895 addRegexToken(token, matchUnsigned); 3896 } 3897 3898 function parseMs (input, array) { 3899 array[MILLISECOND] = toInt(('0.' + input) * 1000); 3900 } 3901 3902 for (token = 'S'; token.length <= 9; token += 'S') { 3903 addParseToken(token, parseMs); 3904 } 3905 // MOMENTS 3906 3907 var getSetMillisecond = makeGetSet('Milliseconds', false); 3908 3909 // FORMATTING 3910 3911 addFormatToken('z', 0, 0, 'zoneAbbr'); 3912 addFormatToken('zz', 0, 0, 'zoneName'); 3913 3914 // MOMENTS 3915 3916 function getZoneAbbr () { 3917 return this._isUTC ? 'UTC' : ''; 3918 } 3919 3920 function getZoneName () { 3921 return this._isUTC ? 'Coordinated Universal Time' : ''; 3922 } 3923 3924 var proto = Moment.prototype; 3925 3926 proto.add = add; 3927 proto.calendar = calendar$1; 3928 proto.clone = clone; 3929 proto.diff = diff; 3930 proto.endOf = endOf; 3931 proto.format = format; 3932 proto.from = from; 3933 proto.fromNow = fromNow; 3934 proto.to = to; 3935 proto.toNow = toNow; 3936 proto.get = stringGet; 3937 proto.invalidAt = invalidAt; 3938 proto.isAfter = isAfter; 3939 proto.isBefore = isBefore; 3940 proto.isBetween = isBetween; 3941 proto.isSame = isSame; 3942 proto.isSameOrAfter = isSameOrAfter; 3943 proto.isSameOrBefore = isSameOrBefore; 3944 proto.isValid = isValid$2; 3945 proto.lang = lang; 3946 proto.locale = locale; 3947 proto.localeData = localeData; 3948 proto.max = prototypeMax; 3949 proto.min = prototypeMin; 3950 proto.parsingFlags = parsingFlags; 3951 proto.set = stringSet; 3952 proto.startOf = startOf; 3953 proto.subtract = subtract; 3954 proto.toArray = toArray; 3955 proto.toObject = toObject; 3956 proto.toDate = toDate; 3957 proto.toISOString = toISOString; 3958 proto.inspect = inspect; 3959 proto.toJSON = toJSON; 3960 proto.toString = toString; 3961 proto.unix = unix; 3962 proto.valueOf = valueOf; 3963 proto.creationData = creationData; 3964 proto.year = getSetYear; 3965 proto.isLeapYear = getIsLeapYear; 3966 proto.weekYear = getSetWeekYear; 3967 proto.isoWeekYear = getSetISOWeekYear; 3968 proto.quarter = proto.quarters = getSetQuarter; 3969 proto.month = getSetMonth; 3970 proto.daysInMonth = getDaysInMonth; 3971 proto.week = proto.weeks = getSetWeek; 3972 proto.isoWeek = proto.isoWeeks = getSetISOWeek; 3973 proto.weeksInYear = getWeeksInYear; 3974 proto.isoWeeksInYear = getISOWeeksInYear; 3975 proto.date = getSetDayOfMonth; 3976 proto.day = proto.days = getSetDayOfWeek; 3977 proto.weekday = getSetLocaleDayOfWeek; 3978 proto.isoWeekday = getSetISODayOfWeek; 3979 proto.dayOfYear = getSetDayOfYear; 3980 proto.hour = proto.hours = getSetHour; 3981 proto.minute = proto.minutes = getSetMinute; 3982 proto.second = proto.seconds = getSetSecond; 3983 proto.millisecond = proto.milliseconds = getSetMillisecond; 3984 proto.utcOffset = getSetOffset; 3985 proto.utc = setOffsetToUTC; 3986 proto.local = setOffsetToLocal; 3987 proto.parseZone = setOffsetToParsedOffset; 3988 proto.hasAlignedHourOffset = hasAlignedHourOffset; 3989 proto.isDST = isDaylightSavingTime; 3990 proto.isLocal = isLocal; 3991 proto.isUtcOffset = isUtcOffset; 3992 proto.isUtc = isUtc; 3993 proto.isUTC = isUtc; 3994 proto.zoneAbbr = getZoneAbbr; 3995 proto.zoneName = getZoneName; 3996 proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); 3997 proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); 3998 proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); 3999 proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); 4000 proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); 4001 4002 function createUnix (input) { 4003 return createLocal(input * 1000); 4004 } 4005 4006 function createInZone () { 4007 return createLocal.apply(null, arguments).parseZone(); 4008 } 4009 4010 function preParsePostFormat (string) { 4011 return string; 4012 } 4013 4014 var proto$1 = Locale.prototype; 4015 4016 proto$1.calendar = calendar; 4017 proto$1.longDateFormat = longDateFormat; 4018 proto$1.invalidDate = invalidDate; 4019 proto$1.ordinal = ordinal; 4020 proto$1.preparse = preParsePostFormat; 4021 proto$1.postformat = preParsePostFormat; 4022 proto$1.relativeTime = relativeTime; 4023 proto$1.pastFuture = pastFuture; 4024 proto$1.set = set; 4025 4026 proto$1.months = localeMonths; 4027 proto$1.monthsShort = localeMonthsShort; 4028 proto$1.monthsParse = localeMonthsParse; 4029 proto$1.monthsRegex = monthsRegex; 4030 proto$1.monthsShortRegex = monthsShortRegex; 4031 proto$1.week = localeWeek; 4032 proto$1.firstDayOfYear = localeFirstDayOfYear; 4033 proto$1.firstDayOfWeek = localeFirstDayOfWeek; 4034 4035 proto$1.weekdays = localeWeekdays; 4036 proto$1.weekdaysMin = localeWeekdaysMin; 4037 proto$1.weekdaysShort = localeWeekdaysShort; 4038 proto$1.weekdaysParse = localeWeekdaysParse; 4039 4040 proto$1.weekdaysRegex = weekdaysRegex; 4041 proto$1.weekdaysShortRegex = weekdaysShortRegex; 4042 proto$1.weekdaysMinRegex = weekdaysMinRegex; 4043 4044 proto$1.isPM = localeIsPM; 4045 proto$1.meridiem = localeMeridiem; 4046 4047 function get$1 (format, index, field, setter) { 4048 var locale = getLocale(); 4049 var utc = createUTC().set(setter, index); 4050 return locale[field](utc, format); 4051 } 4052 4053 function listMonthsImpl (format, index, field) { 4054 if (isNumber(format)) { 4055 index = format; 4056 format = undefined; 4057 } 4058 4059 format = format || ''; 4060 4061 if (index != null) { 4062 return get$1(format, index, field, 'month'); 4063 } 4064 4065 var i; 4066 var out = []; 4067 for (i = 0; i < 12; i++) { 4068 out[i] = get$1(format, i, field, 'month'); 4069 } 4070 return out; 4071 } 4072 4073 // () 4074 // (5) 4075 // (fmt, 5) 4076 // (fmt) 4077 // (true) 4078 // (true, 5) 4079 // (true, fmt, 5) 4080 // (true, fmt) 4081 function listWeekdaysImpl (localeSorted, format, index, field) { 4082 if (typeof localeSorted === 'boolean') { 4083 if (isNumber(format)) { 4084 index = format; 4085 format = undefined; 4086 } 4087 4088 format = format || ''; 4089 } else { 4090 format = localeSorted; 4091 index = format; 4092 localeSorted = false; 4093 4094 if (isNumber(format)) { 4095 index = format; 4096 format = undefined; 4097 } 4098 4099 format = format || ''; 4100 } 4101 4102 var locale = getLocale(), 4103 shift = localeSorted ? locale._week.dow : 0; 4104 4105 if (index != null) { 4106 return get$1(format, (index + shift) % 7, field, 'day'); 4107 } 4108 4109 var i; 4110 var out = []; 4111 for (i = 0; i < 7; i++) { 4112 out[i] = get$1(format, (i + shift) % 7, field, 'day'); 4113 } 4114 return out; 4115 } 4116 4117 function listMonths (format, index) { 4118 return listMonthsImpl(format, index, 'months'); 4119 } 4120 4121 function listMonthsShort (format, index) { 4122 return listMonthsImpl(format, index, 'monthsShort'); 4123 } 4124 4125 function listWeekdays (localeSorted, format, index) { 4126 return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); 4127 } 4128 4129 function listWeekdaysShort (localeSorted, format, index) { 4130 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); 4131 } 4132 4133 function listWeekdaysMin (localeSorted, format, index) { 4134 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); 4135 } 4136 4137 getSetGlobalLocale('en', { 4138 dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, 4139 ordinal: function (number) { 4140 var b = number % 10, 4141 output = (toInt(number % 100 / 10) === 1) ? 'th' : 4142 (b === 1) ? 'st' : 4143 (b === 2) ? 'nd' : 4144 (b === 3) ? 'rd' : 'th'; 4145 return number + output; 4146 } 4147 }); 4148 4149 // Side effect imports 4150 4151 hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); 4152 hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); 4153 4154 var mathAbs = Math.abs; 4155 4156 function abs () { 4157 var data = this._data; 4158 4159 this._milliseconds = mathAbs(this._milliseconds); 4160 this._days = mathAbs(this._days); 4161 this._months = mathAbs(this._months); 4162 4163 data.milliseconds = mathAbs(data.milliseconds); 4164 data.seconds = mathAbs(data.seconds); 4165 data.minutes = mathAbs(data.minutes); 4166 data.hours = mathAbs(data.hours); 4167 data.months = mathAbs(data.months); 4168 data.years = mathAbs(data.years); 4169 4170 return this; 4171 } 4172 4173 function addSubtract$1 (duration, input, value, direction) { 4174 var other = createDuration(input, value); 4175 4176 duration._milliseconds += direction * other._milliseconds; 4177 duration._days += direction * other._days; 4178 duration._months += direction * other._months; 4179 4180 return duration._bubble(); 4181 } 4182 4183 // supports only 2.0-style add(1, 's') or add(duration) 4184 function add$1 (input, value) { 4185 return addSubtract$1(this, input, value, 1); 4186 } 4187 4188 // supports only 2.0-style subtract(1, 's') or subtract(duration) 4189 function subtract$1 (input, value) { 4190 return addSubtract$1(this, input, value, -1); 4191 } 4192 4193 function absCeil (number) { 4194 if (number < 0) { 4195 return Math.floor(number); 4196 } else { 4197 return Math.ceil(number); 4198 } 4199 } 4200 4201 function bubble () { 4202 var milliseconds = this._milliseconds; 4203 var days = this._days; 4204 var months = this._months; 4205 var data = this._data; 4206 var seconds, minutes, hours, years, monthsFromDays; 4207 4208 // if we have a mix of positive and negative values, bubble down first 4209 // check: https://github.com/moment/moment/issues/2166 4210 if (!((milliseconds >= 0 && days >= 0 && months >= 0) || 4211 (milliseconds <= 0 && days <= 0 && months <= 0))) { 4212 milliseconds += absCeil(monthsToDays(months) + days) * 864e5; 4213 days = 0; 4214 months = 0; 4215 } 4216 4217 // The following code bubbles up values, see the tests for 4218 // examples of what that means. 4219 data.milliseconds = milliseconds % 1000; 4220 4221 seconds = absFloor(milliseconds / 1000); 4222 data.seconds = seconds % 60; 4223 4224 minutes = absFloor(seconds / 60); 4225 data.minutes = minutes % 60; 4226 4227 hours = absFloor(minutes / 60); 4228 data.hours = hours % 24; 4229 4230 days += absFloor(hours / 24); 4231 4232 // convert days to months 4233 monthsFromDays = absFloor(daysToMonths(days)); 4234 months += monthsFromDays; 4235 days -= absCeil(monthsToDays(monthsFromDays)); 4236 4237 // 12 months -> 1 year 4238 years = absFloor(months / 12); 4239 months %= 12; 4240 4241 data.days = days; 4242 data.months = months; 4243 data.years = years; 4244 4245 return this; 4246 } 4247 4248 function daysToMonths (days) { 4249 // 400 years have 146097 days (taking into account leap year rules) 4250 // 400 years have 12 months === 4800 4251 return days * 4800 / 146097; 4252 } 4253 4254 function monthsToDays (months) { 4255 // the reverse of daysToMonths 4256 return months * 146097 / 4800; 4257 } 4258 4259 function as (units) { 4260 if (!this.isValid()) { 4261 return NaN; 4262 } 4263 var days; 4264 var months; 4265 var milliseconds = this._milliseconds; 4266 4267 units = normalizeUnits(units); 4268 4269 if (units === 'month' || units === 'quarter' || units === 'year') { 4270 days = this._days + milliseconds / 864e5; 4271 months = this._months + daysToMonths(days); 4272 switch (units) { 4273 case 'month': return months; 4274 case 'quarter': return months / 3; 4275 case 'year': return months / 12; 4276 } 4277 } else { 4278 // handle milliseconds separately because of floating point math errors (issue #1867) 4279 days = this._days + Math.round(monthsToDays(this._months)); 4280 switch (units) { 4281 case 'week': return days / 7 + milliseconds / 6048e5; 4282 case 'day': return days + milliseconds / 864e5; 4283 case 'hour': return days * 24 + milliseconds / 36e5; 4284 case 'minute': return days * 1440 + milliseconds / 6e4; 4285 case 'second': return days * 86400 + milliseconds / 1000; 4286 // Math.floor prevents floating point math errors here 4287 case 'millisecond': return Math.floor(days * 864e5) + milliseconds; 4288 default: throw new Error('Unknown unit ' + units); 4289 } 4290 } 4291 } 4292 4293 // TODO: Use this.as('ms')? 4294 function valueOf$1 () { 4295 if (!this.isValid()) { 4296 return NaN; 4297 } 4298 return ( 4299 this._milliseconds + 4300 this._days * 864e5 + 4301 (this._months % 12) * 2592e6 + 4302 toInt(this._months / 12) * 31536e6 4303 ); 4304 } 4305 4306 function makeAs (alias) { 4307 return function () { 4308 return this.as(alias); 4309 }; 4310 } 4311 4312 var asMilliseconds = makeAs('ms'); 4313 var asSeconds = makeAs('s'); 4314 var asMinutes = makeAs('m'); 4315 var asHours = makeAs('h'); 4316 var asDays = makeAs('d'); 4317 var asWeeks = makeAs('w'); 4318 var asMonths = makeAs('M'); 4319 var asQuarters = makeAs('Q'); 4320 var asYears = makeAs('y'); 4321 4322 function clone$1 () { 4323 return createDuration(this); 4324 } 4325 4326 function get$2 (units) { 4327 units = normalizeUnits(units); 4328 return this.isValid() ? this[units + 's']() : NaN; 4329 } 4330 4331 function makeGetter (name) { 4332 return function () { 4333 return this.isValid() ? this._data[name] : NaN; 4334 }; 4335 } 4336 4337 var milliseconds = makeGetter('milliseconds'); 4338 var seconds = makeGetter('seconds'); 4339 var minutes = makeGetter('minutes'); 4340 var hours = makeGetter('hours'); 4341 var days = makeGetter('days'); 4342 var months = makeGetter('months'); 4343 var years = makeGetter('years'); 4344 4345 function weeks () { 4346 return absFloor(this.days() / 7); 4347 } 4348 4349 var round = Math.round; 4350 var thresholds = { 4351 ss: 44, // a few seconds to seconds 4352 s: 45, // seconds to minute 4353 m: 45, // minutes to hour 4354 h: 22, // hours to day 4355 d: 26, // days to month 4356 M: 11 // months to year 4357 }; 4358 4359 // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize 4360 function substituteTimeAgo (string, number, withoutSuffix, isFuture, locale) { 4361 return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); 4362 } 4363 4364 function relativeTime$1 (posNegDuration, withoutSuffix, locale) { 4365 var duration = createDuration(posNegDuration).abs(); 4366 var seconds = round(duration.as('s')); 4367 var minutes = round(duration.as('m')); 4368 var hours = round(duration.as('h')); 4369 var days = round(duration.as('d')); 4370 var months = round(duration.as('M')); 4371 var years = round(duration.as('y')); 4372 4373 var a = seconds <= thresholds.ss && ['s', seconds] || 4374 seconds < thresholds.s && ['ss', seconds] || 4375 minutes <= 1 && ['m'] || 4376 minutes < thresholds.m && ['mm', minutes] || 4377 hours <= 1 && ['h'] || 4378 hours < thresholds.h && ['hh', hours] || 4379 days <= 1 && ['d'] || 4380 days < thresholds.d && ['dd', days] || 4381 months <= 1 && ['M'] || 4382 months < thresholds.M && ['MM', months] || 4383 years <= 1 && ['y'] || ['yy', years]; 4384 4385 a[2] = withoutSuffix; 4386 a[3] = +posNegDuration > 0; 4387 a[4] = locale; 4388 return substituteTimeAgo.apply(null, a); 4389 } 4390 4391 // This function allows you to set the rounding function for relative time strings 4392 function getSetRelativeTimeRounding (roundingFunction) { 4393 if (roundingFunction === undefined) { 4394 return round; 4395 } 4396 if (typeof (roundingFunction) === 'function') { 4397 round = roundingFunction; 4398 return true; 4399 } 4400 return false; 4401 } 4402 4403 // This function allows you to set a threshold for relative time strings 4404 function getSetRelativeTimeThreshold (threshold, limit) { 4405 if (thresholds[threshold] === undefined) { 4406 return false; 4407 } 4408 if (limit === undefined) { 4409 return thresholds[threshold]; 4410 } 4411 thresholds[threshold] = limit; 4412 if (threshold === 's') { 4413 thresholds.ss = limit - 1; 4414 } 4415 return true; 4416 } 4417 4418 function humanize (withSuffix) { 4419 if (!this.isValid()) { 4420 return this.localeData().invalidDate(); 4421 } 4422 4423 var locale = this.localeData(); 4424 var output = relativeTime$1(this, !withSuffix, locale); 4425 4426 if (withSuffix) { 4427 output = locale.pastFuture(+this, output); 4428 } 4429 4430 return locale.postformat(output); 4431 } 4432 4433 var abs$1 = Math.abs; 4434 4435 function sign (x) { 4436 return ((x > 0) - (x < 0)) || +x; 4437 } 4438 4439 function toISOString$1 () { 4440 // for ISO strings we do not use the normal bubbling rules: 4441 // * milliseconds bubble up until they become hours 4442 // * days do not bubble at all 4443 // * months bubble up until they become years 4444 // This is because there is no context-free conversion between hours and days 4445 // (think of clock changes) 4446 // and also not between days and months (28-31 days per month) 4447 if (!this.isValid()) { 4448 return this.localeData().invalidDate(); 4449 } 4450 4451 var seconds = abs$1(this._milliseconds) / 1000; 4452 var days = abs$1(this._days); 4453 var months = abs$1(this._months); 4454 var minutes, hours, years; 4455 4456 // 3600 seconds -> 60 minutes -> 1 hour 4457 minutes = absFloor(seconds / 60); 4458 hours = absFloor(minutes / 60); 4459 seconds %= 60; 4460 minutes %= 60; 4461 4462 // 12 months -> 1 year 4463 years = absFloor(months / 12); 4464 months %= 12; 4465 4466 4467 // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js 4468 var Y = years; 4469 var M = months; 4470 var D = days; 4471 var h = hours; 4472 var m = minutes; 4473 var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; 4474 var total = this.asSeconds(); 4475 4476 if (!total) { 4477 // this is the same as C#'s (Noda) and python (isodate)... 4478 // but not other JS (goog.date) 4479 return 'P0D'; 4480 } 4481 4482 var totalSign = total < 0 ? '-' : ''; 4483 var ymSign = sign(this._months) !== sign(total) ? '-' : ''; 4484 var daysSign = sign(this._days) !== sign(total) ? '-' : ''; 4485 var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; 4486 4487 return totalSign + 'P' + 4488 (Y ? ymSign + Y + 'Y' : '') + 4489 (M ? ymSign + M + 'M' : '') + 4490 (D ? daysSign + D + 'D' : '') + 4491 ((h || m || s) ? 'T' : '') + 4492 (h ? hmsSign + h + 'H' : '') + 4493 (m ? hmsSign + m + 'M' : '') + 4494 (s ? hmsSign + s + 'S' : ''); 4495 } 4496 4497 var proto$2 = Duration.prototype; 4498 4499 proto$2.isValid = isValid$1; 4500 proto$2.abs = abs; 4501 proto$2.add = add$1; 4502 proto$2.subtract = subtract$1; 4503 proto$2.as = as; 4504 proto$2.asMilliseconds = asMilliseconds; 4505 proto$2.asSeconds = asSeconds; 4506 proto$2.asMinutes = asMinutes; 4507 proto$2.asHours = asHours; 4508 proto$2.asDays = asDays; 4509 proto$2.asWeeks = asWeeks; 4510 proto$2.asMonths = asMonths; 4511 proto$2.asQuarters = asQuarters; 4512 proto$2.asYears = asYears; 4513 proto$2.valueOf = valueOf$1; 4514 proto$2._bubble = bubble; 4515 proto$2.clone = clone$1; 4516 proto$2.get = get$2; 4517 proto$2.milliseconds = milliseconds; 4518 proto$2.seconds = seconds; 4519 proto$2.minutes = minutes; 4520 proto$2.hours = hours; 4521 proto$2.days = days; 4522 proto$2.weeks = weeks; 4523 proto$2.months = months; 4524 proto$2.years = years; 4525 proto$2.humanize = humanize; 4526 proto$2.toISOString = toISOString$1; 4527 proto$2.toString = toISOString$1; 4528 proto$2.toJSON = toISOString$1; 4529 proto$2.locale = locale; 4530 proto$2.localeData = localeData; 4531 4532 proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); 4533 proto$2.lang = lang; 4534 4535 // Side effect imports 4536 4537 // FORMATTING 4538 4539 addFormatToken('X', 0, 0, 'unix'); 4540 addFormatToken('x', 0, 0, 'valueOf'); 4541 4542 // PARSING 4543 4544 addRegexToken('x', matchSigned);
4545 addRegexToken('X', matchTimestamp); 4546 addParseToken('X', function (input, array, config) { 4547 config._d = new Date(parseFloat(input, 10) * 1000); 4548 }); 4549 addParseToken('x', function (input, array, config) { 4550 config._d = new Date(toInt(input)); 4551 }); 4552 4553 // Side effect imports 4554 4555 4556 hooks.version = '2.24.0'; 4557 4558 setHookCallback(createLocal); 4559 4560 hooks.fn = proto; 4561 hooks.min = min; 4562 hooks.max = max; 4563 hooks.now = now; 4564 hooks.utc = createUTC; 4565 hooks.unix = createUnix; 4566 hooks.months = listMonths; 4567 hooks.isDate = isDate; 4568 hooks.locale = getSetGlobalLocale; 4569 hooks.invalid = createInvalid; 4570 hooks.duration = createDuration; 4571 hooks.isMoment = isMoment; 4572 hooks.weekdays = listWeekdays; 4573 hooks.parseZone = createInZone; 4574 hooks.localeData = getLocale; 4575 hooks.isDuration = isDuration; 4576 hooks.monthsShort = listMonthsShort; 4577 hooks.weekdaysMin = listWeekdaysMin; 4578 hooks.defineLocale = defineLocale; 4579 hooks.updateLocale = updateLocale; 4580 hooks.locales = listLocales; 4581 hooks.weekdaysShort = listWeekdaysShort; 4582 hooks.normalizeUnits = normalizeUnits; 4583 hooks.relativeTimeRounding = getSetRelativeTimeRounding; 4584 hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; 4585 hooks.calendarFormat = getCalendarFormat; 4586 hooks.prototype = proto; 4587 4588 // currently HTML5 input type only supports 24-hour formats 4589 hooks.HTML5_FMT = { 4590 DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" /> 4591 DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" /> 4592 DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" /> 4593 DATE: 'YYYY-MM-DD', // <input type="date" /> 4594 TIME: 'HH:mm', // <input type="time" /> 4595 TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" /> 4596 TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" /> 4597 WEEK: 'GGGG-[W]WW', // <input type="week" /> 4598 MONTH: 'YYYY-MM' // <input type="month" /> 4599 }; 4600 4601 return hooks; 4602 4603 })));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.