UNPKG

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