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