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