UNPKG

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