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