Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
malwaredllc
GitHub Repository: malwaredllc/byob
Path: blob/master/web-gui/buildyourownbotnet/assets/js/daterangepicker/moment.js
1293 views
1
//! moment.js
2
//! version : 2.9.0
3
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
4
//! license : MIT
5
//! momentjs.com
6
7
(function (undefined) {
8
/************************************
9
Constants
10
************************************/
11
12
var moment,
13
VERSION = '2.9.0',
14
// the global-scope this is NOT the global object in Node.js
15
globalScope = (typeof global !== 'undefined' && (typeof window === 'undefined' || window === global.window)) ? global : this,
16
oldGlobalMoment,
17
round = Math.round,
18
hasOwnProperty = Object.prototype.hasOwnProperty,
19
i,
20
21
YEAR = 0,
22
MONTH = 1,
23
DATE = 2,
24
HOUR = 3,
25
MINUTE = 4,
26
SECOND = 5,
27
MILLISECOND = 6,
28
29
// internal storage for locale config files
30
locales = {},
31
32
// extra moment internal properties (plugins register props here)
33
momentProperties = [],
34
35
// check for nodeJS
36
hasModule = (typeof module !== 'undefined' && module && module.exports),
37
38
// ASP.NET json date format regex
39
aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
40
aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,
41
42
// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
43
// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
44
isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,
45
46
// format tokens
47
formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g,
48
localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,
49
50
// parsing token regexes
51
parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99
52
parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999
53
parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999
54
parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
55
parseTokenDigits = /\d+/, // nonzero number of digits
56
parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic.
57
parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
58
parseTokenT = /T/i, // T (ISO separator)
59
parseTokenOffsetMs = /[\+\-]?\d+/, // 1234567890123
60
parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
61
62
//strict parsing regexes
63
parseTokenOneDigit = /\d/, // 0 - 9
64
parseTokenTwoDigits = /\d\d/, // 00 - 99
65
parseTokenThreeDigits = /\d{3}/, // 000 - 999
66
parseTokenFourDigits = /\d{4}/, // 0000 - 9999
67
parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999
68
parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf
69
70
// iso 8601 regex
71
// 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)
72
isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
73
74
isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
75
76
isoDates = [
77
['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
78
['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
79
['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
80
['GGGG-[W]WW', /\d{4}-W\d{2}/],
81
['YYYY-DDD', /\d{4}-\d{3}/]
82
],
83
84
// iso time formats and regexes
85
isoTimes = [
86
['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/],
87
['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
88
['HH:mm', /(T| )\d\d:\d\d/],
89
['HH', /(T| )\d\d/]
90
],
91
92
// timezone chunker '+10:00' > ['10', '00'] or '-1530' > ['-', '15', '30']
93
parseTimezoneChunker = /([\+\-]|\d\d)/gi,
94
95
// getter and setter names
96
proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
97
unitMillisecondFactors = {
98
'Milliseconds' : 1,
99
'Seconds' : 1e3,
100
'Minutes' : 6e4,
101
'Hours' : 36e5,
102
'Days' : 864e5,
103
'Months' : 2592e6,
104
'Years' : 31536e6
105
},
106
107
unitAliases = {
108
ms : 'millisecond',
109
s : 'second',
110
m : 'minute',
111
h : 'hour',
112
d : 'day',
113
D : 'date',
114
w : 'week',
115
W : 'isoWeek',
116
M : 'month',
117
Q : 'quarter',
118
y : 'year',
119
DDD : 'dayOfYear',
120
e : 'weekday',
121
E : 'isoWeekday',
122
gg: 'weekYear',
123
GG: 'isoWeekYear'
124
},
125
126
camelFunctions = {
127
dayofyear : 'dayOfYear',
128
isoweekday : 'isoWeekday',
129
isoweek : 'isoWeek',
130
weekyear : 'weekYear',
131
isoweekyear : 'isoWeekYear'
132
},
133
134
// format function strings
135
formatFunctions = {},
136
137
// default relative time thresholds
138
relativeTimeThresholds = {
139
s: 45, // seconds to minute
140
m: 45, // minutes to hour
141
h: 22, // hours to day
142
d: 26, // days to month
143
M: 11 // months to year
144
},
145
146
// tokens to ordinalize and pad
147
ordinalizeTokens = 'DDD w W M D d'.split(' '),
148
paddedTokens = 'M D H h m s w W'.split(' '),
149
150
formatTokenFunctions = {
151
M : function () {
152
return this.month() + 1;
153
},
154
MMM : function (format) {
155
return this.localeData().monthsShort(this, format);
156
},
157
MMMM : function (format) {
158
return this.localeData().months(this, format);
159
},
160
D : function () {
161
return this.date();
162
},
163
DDD : function () {
164
return this.dayOfYear();
165
},
166
d : function () {
167
return this.day();
168
},
169
dd : function (format) {
170
return this.localeData().weekdaysMin(this, format);
171
},
172
ddd : function (format) {
173
return this.localeData().weekdaysShort(this, format);
174
},
175
dddd : function (format) {
176
return this.localeData().weekdays(this, format);
177
},
178
w : function () {
179
return this.week();
180
},
181
W : function () {
182
return this.isoWeek();
183
},
184
YY : function () {
185
return leftZeroFill(this.year() % 100, 2);
186
},
187
YYYY : function () {
188
return leftZeroFill(this.year(), 4);
189
},
190
YYYYY : function () {
191
return leftZeroFill(this.year(), 5);
192
},
193
YYYYYY : function () {
194
var y = this.year(), sign = y >= 0 ? '+' : '-';
195
return sign + leftZeroFill(Math.abs(y), 6);
196
},
197
gg : function () {
198
return leftZeroFill(this.weekYear() % 100, 2);
199
},
200
gggg : function () {
201
return leftZeroFill(this.weekYear(), 4);
202
},
203
ggggg : function () {
204
return leftZeroFill(this.weekYear(), 5);
205
},
206
GG : function () {
207
return leftZeroFill(this.isoWeekYear() % 100, 2);
208
},
209
GGGG : function () {
210
return leftZeroFill(this.isoWeekYear(), 4);
211
},
212
GGGGG : function () {
213
return leftZeroFill(this.isoWeekYear(), 5);
214
},
215
e : function () {
216
return this.weekday();
217
},
218
E : function () {
219
return this.isoWeekday();
220
},
221
a : function () {
222
return this.localeData().meridiem(this.hours(), this.minutes(), true);
223
},
224
A : function () {
225
return this.localeData().meridiem(this.hours(), this.minutes(), false);
226
},
227
H : function () {
228
return this.hours();
229
},
230
h : function () {
231
return this.hours() % 12 || 12;
232
},
233
m : function () {
234
return this.minutes();
235
},
236
s : function () {
237
return this.seconds();
238
},
239
S : function () {
240
return toInt(this.milliseconds() / 100);
241
},
242
SS : function () {
243
return leftZeroFill(toInt(this.milliseconds() / 10), 2);
244
},
245
SSS : function () {
246
return leftZeroFill(this.milliseconds(), 3);
247
},
248
SSSS : function () {
249
return leftZeroFill(this.milliseconds(), 3);
250
},
251
Z : function () {
252
var a = this.utcOffset(),
253
b = '+';
254
if (a < 0) {
255
a = -a;
256
b = '-';
257
}
258
return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2);
259
},
260
ZZ : function () {
261
var a = this.utcOffset(),
262
b = '+';
263
if (a < 0) {
264
a = -a;
265
b = '-';
266
}
267
return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
268
},
269
z : function () {
270
return this.zoneAbbr();
271
},
272
zz : function () {
273
return this.zoneName();
274
},
275
x : function () {
276
return this.valueOf();
277
},
278
X : function () {
279
return this.unix();
280
},
281
Q : function () {
282
return this.quarter();
283
}
284
},
285
286
deprecations = {},
287
288
lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'],
289
290
updateInProgress = false;
291
292
// Pick the first defined of two or three arguments. dfl comes from
293
// default.
294
function dfl(a, b, c) {
295
switch (arguments.length) {
296
case 2: return a != null ? a : b;
297
case 3: return a != null ? a : b != null ? b : c;
298
default: throw new Error('Implement me');
299
}
300
}
301
302
function hasOwnProp(a, b) {
303
return hasOwnProperty.call(a, b);
304
}
305
306
function defaultParsingFlags() {
307
// We need to deep clone this object, and es5 standard is not very
308
// helpful.
309
return {
310
empty : false,
311
unusedTokens : [],
312
unusedInput : [],
313
overflow : -2,
314
charsLeftOver : 0,
315
nullInput : false,
316
invalidMonth : null,
317
invalidFormat : false,
318
userInvalidated : false,
319
iso: false
320
};
321
}
322
323
function printMsg(msg) {
324
if (moment.suppressDeprecationWarnings === false &&
325
typeof console !== 'undefined' && console.warn) {
326
console.warn('Deprecation warning: ' + msg);
327
}
328
}
329
330
function deprecate(msg, fn) {
331
var firstTime = true;
332
return extend(function () {
333
if (firstTime) {
334
printMsg(msg);
335
firstTime = false;
336
}
337
return fn.apply(this, arguments);
338
}, fn);
339
}
340
341
function deprecateSimple(name, msg) {
342
if (!deprecations[name]) {
343
printMsg(msg);
344
deprecations[name] = true;
345
}
346
}
347
348
function padToken(func, count) {
349
return function (a) {
350
return leftZeroFill(func.call(this, a), count);
351
};
352
}
353
function ordinalizeToken(func, period) {
354
return function (a) {
355
return this.localeData().ordinal(func.call(this, a), period);
356
};
357
}
358
359
function monthDiff(a, b) {
360
// difference in months
361
var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
362
// b is in (anchor - 1 month, anchor + 1 month)
363
anchor = a.clone().add(wholeMonthDiff, 'months'),
364
anchor2, adjust;
365
366
if (b - anchor < 0) {
367
anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
368
// linear across the month
369
adjust = (b - anchor) / (anchor - anchor2);
370
} else {
371
anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
372
// linear across the month
373
adjust = (b - anchor) / (anchor2 - anchor);
374
}
375
376
return -(wholeMonthDiff + adjust);
377
}
378
379
while (ordinalizeTokens.length) {
380
i = ordinalizeTokens.pop();
381
formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);
382
}
383
while (paddedTokens.length) {
384
i = paddedTokens.pop();
385
formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);
386
}
387
formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);
388
389
390
function meridiemFixWrap(locale, hour, meridiem) {
391
var isPm;
392
393
if (meridiem == null) {
394
// nothing to do
395
return hour;
396
}
397
if (locale.meridiemHour != null) {
398
return locale.meridiemHour(hour, meridiem);
399
} else if (locale.isPM != null) {
400
// Fallback
401
isPm = locale.isPM(meridiem);
402
if (isPm && hour < 12) {
403
hour += 12;
404
}
405
if (!isPm && hour === 12) {
406
hour = 0;
407
}
408
return hour;
409
} else {
410
// thie is not supposed to happen
411
return hour;
412
}
413
}
414
415
/************************************
416
Constructors
417
************************************/
418
419
function Locale() {
420
}
421
422
// Moment prototype object
423
function Moment(config, skipOverflow) {
424
if (skipOverflow !== false) {
425
checkOverflow(config);
426
}
427
copyConfig(this, config);
428
this._d = new Date(+config._d);
429
// Prevent infinite loop in case updateOffset creates new moment
430
// objects.
431
if (updateInProgress === false) {
432
updateInProgress = true;
433
moment.updateOffset(this);
434
updateInProgress = false;
435
}
436
}
437
438
// Duration Constructor
439
function Duration(duration) {
440
var normalizedInput = normalizeObjectUnits(duration),
441
years = normalizedInput.year || 0,
442
quarters = normalizedInput.quarter || 0,
443
months = normalizedInput.month || 0,
444
weeks = normalizedInput.week || 0,
445
days = normalizedInput.day || 0,
446
hours = normalizedInput.hour || 0,
447
minutes = normalizedInput.minute || 0,
448
seconds = normalizedInput.second || 0,
449
milliseconds = normalizedInput.millisecond || 0;
450
451
// representation for dateAddRemove
452
this._milliseconds = +milliseconds +
453
seconds * 1e3 + // 1000
454
minutes * 6e4 + // 1000 * 60
455
hours * 36e5; // 1000 * 60 * 60
456
// Because of dateAddRemove treats 24 hours as different from a
457
// day when working around DST, we need to store them separately
458
this._days = +days +
459
weeks * 7;
460
// It is impossible translate months into days without knowing
461
// which months you are are talking about, so we have to store
462
// it separately.
463
this._months = +months +
464
quarters * 3 +
465
years * 12;
466
467
this._data = {};
468
469
this._locale = moment.localeData();
470
471
this._bubble();
472
}
473
474
/************************************
475
Helpers
476
************************************/
477
478
479
function extend(a, b) {
480
for (var i in b) {
481
if (hasOwnProp(b, i)) {
482
a[i] = b[i];
483
}
484
}
485
486
if (hasOwnProp(b, 'toString')) {
487
a.toString = b.toString;
488
}
489
490
if (hasOwnProp(b, 'valueOf')) {
491
a.valueOf = b.valueOf;
492
}
493
494
return a;
495
}
496
497
function copyConfig(to, from) {
498
var i, prop, val;
499
500
if (typeof from._isAMomentObject !== 'undefined') {
501
to._isAMomentObject = from._isAMomentObject;
502
}
503
if (typeof from._i !== 'undefined') {
504
to._i = from._i;
505
}
506
if (typeof from._f !== 'undefined') {
507
to._f = from._f;
508
}
509
if (typeof from._l !== 'undefined') {
510
to._l = from._l;
511
}
512
if (typeof from._strict !== 'undefined') {
513
to._strict = from._strict;
514
}
515
if (typeof from._tzm !== 'undefined') {
516
to._tzm = from._tzm;
517
}
518
if (typeof from._isUTC !== 'undefined') {
519
to._isUTC = from._isUTC;
520
}
521
if (typeof from._offset !== 'undefined') {
522
to._offset = from._offset;
523
}
524
if (typeof from._pf !== 'undefined') {
525
to._pf = from._pf;
526
}
527
if (typeof from._locale !== 'undefined') {
528
to._locale = from._locale;
529
}
530
531
if (momentProperties.length > 0) {
532
for (i in momentProperties) {
533
prop = momentProperties[i];
534
val = from[prop];
535
if (typeof val !== 'undefined') {
536
to[prop] = val;
537
}
538
}
539
}
540
541
return to;
542
}
543
544
function absRound(number) {
545
if (number < 0) {
546
return Math.ceil(number);
547
} else {
548
return Math.floor(number);
549
}
550
}
551
552
// left zero fill a number
553
// see http://jsperf.com/left-zero-filling for performance comparison
554
function leftZeroFill(number, targetLength, forceSign) {
555
var output = '' + Math.abs(number),
556
sign = number >= 0;
557
558
while (output.length < targetLength) {
559
output = '0' + output;
560
}
561
return (sign ? (forceSign ? '+' : '') : '-') + output;
562
}
563
564
function positiveMomentsDifference(base, other) {
565
var res = {milliseconds: 0, months: 0};
566
567
res.months = other.month() - base.month() +
568
(other.year() - base.year()) * 12;
569
if (base.clone().add(res.months, 'M').isAfter(other)) {
570
--res.months;
571
}
572
573
res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
574
575
return res;
576
}
577
578
function momentsDifference(base, other) {
579
var res;
580
other = makeAs(other, base);
581
if (base.isBefore(other)) {
582
res = positiveMomentsDifference(base, other);
583
} else {
584
res = positiveMomentsDifference(other, base);
585
res.milliseconds = -res.milliseconds;
586
res.months = -res.months;
587
}
588
589
return res;
590
}
591
592
// TODO: remove 'name' arg after deprecation is removed
593
function createAdder(direction, name) {
594
return function (val, period) {
595
var dur, tmp;
596
//invert the arguments, but complain about it
597
if (period !== null && !isNaN(+period)) {
598
deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');
599
tmp = val; val = period; period = tmp;
600
}
601
602
val = typeof val === 'string' ? +val : val;
603
dur = moment.duration(val, period);
604
addOrSubtractDurationFromMoment(this, dur, direction);
605
return this;
606
};
607
}
608
609
function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
610
var milliseconds = duration._milliseconds,
611
days = duration._days,
612
months = duration._months;
613
updateOffset = updateOffset == null ? true : updateOffset;
614
615
if (milliseconds) {
616
mom._d.setTime(+mom._d + milliseconds * isAdding);
617
}
618
if (days) {
619
rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding);
620
}
621
if (months) {
622
rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding);
623
}
624
if (updateOffset) {
625
moment.updateOffset(mom, days || months);
626
}
627
}
628
629
// check if is an array
630
function isArray(input) {
631
return Object.prototype.toString.call(input) === '[object Array]';
632
}
633
634
function isDate(input) {
635
return Object.prototype.toString.call(input) === '[object Date]' ||
636
input instanceof Date;
637
}
638
639
// compare two arrays, return the number of differences
640
function compareArrays(array1, array2, dontConvert) {
641
var len = Math.min(array1.length, array2.length),
642
lengthDiff = Math.abs(array1.length - array2.length),
643
diffs = 0,
644
i;
645
for (i = 0; i < len; i++) {
646
if ((dontConvert && array1[i] !== array2[i]) ||
647
(!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
648
diffs++;
649
}
650
}
651
return diffs + lengthDiff;
652
}
653
654
function normalizeUnits(units) {
655
if (units) {
656
var lowered = units.toLowerCase().replace(/(.)s$/, '$1');
657
units = unitAliases[units] || camelFunctions[lowered] || lowered;
658
}
659
return units;
660
}
661
662
function normalizeObjectUnits(inputObject) {
663
var normalizedInput = {},
664
normalizedProp,
665
prop;
666
667
for (prop in inputObject) {
668
if (hasOwnProp(inputObject, prop)) {
669
normalizedProp = normalizeUnits(prop);
670
if (normalizedProp) {
671
normalizedInput[normalizedProp] = inputObject[prop];
672
}
673
}
674
}
675
676
return normalizedInput;
677
}
678
679
function makeList(field) {
680
var count, setter;
681
682
if (field.indexOf('week') === 0) {
683
count = 7;
684
setter = 'day';
685
}
686
else if (field.indexOf('month') === 0) {
687
count = 12;
688
setter = 'month';
689
}
690
else {
691
return;
692
}
693
694
moment[field] = function (format, index) {
695
var i, getter,
696
method = moment._locale[field],
697
results = [];
698
699
if (typeof format === 'number') {
700
index = format;
701
format = undefined;
702
}
703
704
getter = function (i) {
705
var m = moment().utc().set(setter, i);
706
return method.call(moment._locale, m, format || '');
707
};
708
709
if (index != null) {
710
return getter(index);
711
}
712
else {
713
for (i = 0; i < count; i++) {
714
results.push(getter(i));
715
}
716
return results;
717
}
718
};
719
}
720
721
function toInt(argumentForCoercion) {
722
var coercedNumber = +argumentForCoercion,
723
value = 0;
724
725
if (coercedNumber !== 0 && isFinite(coercedNumber)) {
726
if (coercedNumber >= 0) {
727
value = Math.floor(coercedNumber);
728
} else {
729
value = Math.ceil(coercedNumber);
730
}
731
}
732
733
return value;
734
}
735
736
function daysInMonth(year, month) {
737
return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
738
}
739
740
function weeksInYear(year, dow, doy) {
741
return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week;
742
}
743
744
function daysInYear(year) {
745
return isLeapYear(year) ? 366 : 365;
746
}
747
748
function isLeapYear(year) {
749
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
750
}
751
752
function checkOverflow(m) {
753
var overflow;
754
if (m._a && m._pf.overflow === -2) {
755
overflow =
756
m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH :
757
m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE :
758
m._a[HOUR] < 0 || m._a[HOUR] > 24 ||
759
(m._a[HOUR] === 24 && (m._a[MINUTE] !== 0 ||
760
m._a[SECOND] !== 0 ||
761
m._a[MILLISECOND] !== 0)) ? HOUR :
762
m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE :
763
m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND :
764
m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND :
765
-1;
766
767
if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
768
overflow = DATE;
769
}
770
771
m._pf.overflow = overflow;
772
}
773
}
774
775
function isValid(m) {
776
if (m._isValid == null) {
777
m._isValid = !isNaN(m._d.getTime()) &&
778
m._pf.overflow < 0 &&
779
!m._pf.empty &&
780
!m._pf.invalidMonth &&
781
!m._pf.nullInput &&
782
!m._pf.invalidFormat &&
783
!m._pf.userInvalidated;
784
785
if (m._strict) {
786
m._isValid = m._isValid &&
787
m._pf.charsLeftOver === 0 &&
788
m._pf.unusedTokens.length === 0 &&
789
m._pf.bigHour === undefined;
790
}
791
}
792
return m._isValid;
793
}
794
795
function normalizeLocale(key) {
796
return key ? key.toLowerCase().replace('_', '-') : key;
797
}
798
799
// pick the locale from the array
800
// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
801
// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
802
function chooseLocale(names) {
803
var i = 0, j, next, locale, split;
804
805
while (i < names.length) {
806
split = normalizeLocale(names[i]).split('-');
807
j = split.length;
808
next = normalizeLocale(names[i + 1]);
809
next = next ? next.split('-') : null;
810
while (j > 0) {
811
locale = loadLocale(split.slice(0, j).join('-'));
812
if (locale) {
813
return locale;
814
}
815
if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
816
//the next array item is better than a shallower substring of this one
817
break;
818
}
819
j--;
820
}
821
i++;
822
}
823
return null;
824
}
825
826
function loadLocale(name) {
827
var oldLocale = null;
828
if (!locales[name] && hasModule) {
829
try {
830
oldLocale = moment.locale();
831
require('./locale/' + name);
832
// because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales
833
moment.locale(oldLocale);
834
} catch (e) { }
835
}
836
return locales[name];
837
}
838
839
// Return a moment from input, that is local/utc/utcOffset equivalent to
840
// model.
841
function makeAs(input, model) {
842
var res, diff;
843
if (model._isUTC) {
844
res = model.clone();
845
diff = (moment.isMoment(input) || isDate(input) ?
846
+input : +moment(input)) - (+res);
847
// Use low-level api, because this fn is low-level api.
848
res._d.setTime(+res._d + diff);
849
moment.updateOffset(res, false);
850
return res;
851
} else {
852
return moment(input).local();
853
}
854
}
855
856
/************************************
857
Locale
858
************************************/
859
860
861
extend(Locale.prototype, {
862
863
set : function (config) {
864
var prop, i;
865
for (i in config) {
866
prop = config[i];
867
if (typeof prop === 'function') {
868
this[i] = prop;
869
} else {
870
this['_' + i] = prop;
871
}
872
}
873
// Lenient ordinal parsing accepts just a number in addition to
874
// number + (possibly) stuff coming from _ordinalParseLenient.
875
this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\d{1,2}/.source);
876
},
877
878
_months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
879
months : function (m) {
880
return this._months[m.month()];
881
},
882
883
_monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
884
monthsShort : function (m) {
885
return this._monthsShort[m.month()];
886
},
887
888
monthsParse : function (monthName, format, strict) {
889
var i, mom, regex;
890
891
if (!this._monthsParse) {
892
this._monthsParse = [];
893
this._longMonthsParse = [];
894
this._shortMonthsParse = [];
895
}
896
897
for (i = 0; i < 12; i++) {
898
// make the regex if we don't have it already
899
mom = moment.utc([2000, i]);
900
if (strict && !this._longMonthsParse[i]) {
901
this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
902
this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
903
}
904
if (!strict && !this._monthsParse[i]) {
905
regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
906
this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
907
}
908
// test the regex
909
if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
910
return i;
911
} else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
912
return i;
913
} else if (!strict && this._monthsParse[i].test(monthName)) {
914
return i;
915
}
916
}
917
},
918
919
_weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
920
weekdays : function (m) {
921
return this._weekdays[m.day()];
922
},
923
924
_weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
925
weekdaysShort : function (m) {
926
return this._weekdaysShort[m.day()];
927
},
928
929
_weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
930
weekdaysMin : function (m) {
931
return this._weekdaysMin[m.day()];
932
},
933
934
weekdaysParse : function (weekdayName) {
935
var i, mom, regex;
936
937
if (!this._weekdaysParse) {
938
this._weekdaysParse = [];
939
}
940
941
for (i = 0; i < 7; i++) {
942
// make the regex if we don't have it already
943
if (!this._weekdaysParse[i]) {
944
mom = moment([2000, 1]).day(i);
945
regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
946
this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
947
}
948
// test the regex
949
if (this._weekdaysParse[i].test(weekdayName)) {
950
return i;
951
}
952
}
953
},
954
955
_longDateFormat : {
956
LTS : 'h:mm:ss A',
957
LT : 'h:mm A',
958
L : 'MM/DD/YYYY',
959
LL : 'MMMM D, YYYY',
960
LLL : 'MMMM D, YYYY LT',
961
LLLL : 'dddd, MMMM D, YYYY LT'
962
},
963
longDateFormat : function (key) {
964
var output = this._longDateFormat[key];
965
if (!output && this._longDateFormat[key.toUpperCase()]) {
966
output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
967
return val.slice(1);
968
});
969
this._longDateFormat[key] = output;
970
}
971
return output;
972
},
973
974
isPM : function (input) {
975
// IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
976
// Using charAt should be more compatible.
977
return ((input + '').toLowerCase().charAt(0) === 'p');
978
},
979
980
_meridiemParse : /[ap]\.?m?\.?/i,
981
meridiem : function (hours, minutes, isLower) {
982
if (hours > 11) {
983
return isLower ? 'pm' : 'PM';
984
} else {
985
return isLower ? 'am' : 'AM';
986
}
987
},
988
989
990
_calendar : {
991
sameDay : '[Today at] LT',
992
nextDay : '[Tomorrow at] LT',
993
nextWeek : 'dddd [at] LT',
994
lastDay : '[Yesterday at] LT',
995
lastWeek : '[Last] dddd [at] LT',
996
sameElse : 'L'
997
},
998
calendar : function (key, mom, now) {
999
var output = this._calendar[key];
1000
return typeof output === 'function' ? output.apply(mom, [now]) : output;
1001
},
1002
1003
_relativeTime : {
1004
future : 'in %s',
1005
past : '%s ago',
1006
s : 'a few seconds',
1007
m : 'a minute',
1008
mm : '%d minutes',
1009
h : 'an hour',
1010
hh : '%d hours',
1011
d : 'a day',
1012
dd : '%d days',
1013
M : 'a month',
1014
MM : '%d months',
1015
y : 'a year',
1016
yy : '%d years'
1017
},
1018
1019
relativeTime : function (number, withoutSuffix, string, isFuture) {
1020
var output = this._relativeTime[string];
1021
return (typeof output === 'function') ?
1022
output(number, withoutSuffix, string, isFuture) :
1023
output.replace(/%d/i, number);
1024
},
1025
1026
pastFuture : function (diff, output) {
1027
var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
1028
return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
1029
},
1030
1031
ordinal : function (number) {
1032
return this._ordinal.replace('%d', number);
1033
},
1034
_ordinal : '%d',
1035
_ordinalParse : /\d{1,2}/,
1036
1037
preparse : function (string) {
1038
return string;
1039
},
1040
1041
postformat : function (string) {
1042
return string;
1043
},
1044
1045
week : function (mom) {
1046
return weekOfYear(mom, this._week.dow, this._week.doy).week;
1047
},
1048
1049
_week : {
1050
dow : 0, // Sunday is the first day of the week.
1051
doy : 6 // The week that contains Jan 1st is the first week of the year.
1052
},
1053
1054
firstDayOfWeek : function () {
1055
return this._week.dow;
1056
},
1057
1058
firstDayOfYear : function () {
1059
return this._week.doy;
1060
},
1061
1062
_invalidDate: 'Invalid date',
1063
invalidDate: function () {
1064
return this._invalidDate;
1065
}
1066
});
1067
1068
/************************************
1069
Formatting
1070
************************************/
1071
1072
1073
function removeFormattingTokens(input) {
1074
if (input.match(/\[[\s\S]/)) {
1075
return input.replace(/^\[|\]$/g, '');
1076
}
1077
return input.replace(/\\/g, '');
1078
}
1079
1080
function makeFormatFunction(format) {
1081
var array = format.match(formattingTokens), i, length;
1082
1083
for (i = 0, length = array.length; i < length; i++) {
1084
if (formatTokenFunctions[array[i]]) {
1085
array[i] = formatTokenFunctions[array[i]];
1086
} else {
1087
array[i] = removeFormattingTokens(array[i]);
1088
}
1089
}
1090
1091
return function (mom) {
1092
var output = '';
1093
for (i = 0; i < length; i++) {
1094
output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
1095
}
1096
return output;
1097
};
1098
}
1099
1100
// format date using native date object
1101
function formatMoment(m, format) {
1102
if (!m.isValid()) {
1103
return m.localeData().invalidDate();
1104
}
1105
1106
format = expandFormat(format, m.localeData());
1107
1108
if (!formatFunctions[format]) {
1109
formatFunctions[format] = makeFormatFunction(format);
1110
}
1111
1112
return formatFunctions[format](m);
1113
}
1114
1115
function expandFormat(format, locale) {
1116
var i = 5;
1117
1118
function replaceLongDateFormatTokens(input) {
1119
return locale.longDateFormat(input) || input;
1120
}
1121
1122
localFormattingTokens.lastIndex = 0;
1123
while (i >= 0 && localFormattingTokens.test(format)) {
1124
format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
1125
localFormattingTokens.lastIndex = 0;
1126
i -= 1;
1127
}
1128
1129
return format;
1130
}
1131
1132
1133
/************************************
1134
Parsing
1135
************************************/
1136
1137
1138
// get the regex to find the next token
1139
function getParseRegexForToken(token, config) {
1140
var a, strict = config._strict;
1141
switch (token) {
1142
case 'Q':
1143
return parseTokenOneDigit;
1144
case 'DDDD':
1145
return parseTokenThreeDigits;
1146
case 'YYYY':
1147
case 'GGGG':
1148
case 'gggg':
1149
return strict ? parseTokenFourDigits : parseTokenOneToFourDigits;
1150
case 'Y':
1151
case 'G':
1152
case 'g':
1153
return parseTokenSignedNumber;
1154
case 'YYYYYY':
1155
case 'YYYYY':
1156
case 'GGGGG':
1157
case 'ggggg':
1158
return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
1159
case 'S':
1160
if (strict) {
1161
return parseTokenOneDigit;
1162
}
1163
/* falls through */
1164
case 'SS':
1165
if (strict) {
1166
return parseTokenTwoDigits;
1167
}
1168
/* falls through */
1169
case 'SSS':
1170
if (strict) {
1171
return parseTokenThreeDigits;
1172
}
1173
/* falls through */
1174
case 'DDD':
1175
return parseTokenOneToThreeDigits;
1176
case 'MMM':
1177
case 'MMMM':
1178
case 'dd':
1179
case 'ddd':
1180
case 'dddd':
1181
return parseTokenWord;
1182
case 'a':
1183
case 'A':
1184
return config._locale._meridiemParse;
1185
case 'x':
1186
return parseTokenOffsetMs;
1187
case 'X':
1188
return parseTokenTimestampMs;
1189
case 'Z':
1190
case 'ZZ':
1191
return parseTokenTimezone;
1192
case 'T':
1193
return parseTokenT;
1194
case 'SSSS':
1195
return parseTokenDigits;
1196
case 'MM':
1197
case 'DD':
1198
case 'YY':
1199
case 'GG':
1200
case 'gg':
1201
case 'HH':
1202
case 'hh':
1203
case 'mm':
1204
case 'ss':
1205
case 'ww':
1206
case 'WW':
1207
return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits;
1208
case 'M':
1209
case 'D':
1210
case 'd':
1211
case 'H':
1212
case 'h':
1213
case 'm':
1214
case 's':
1215
case 'w':
1216
case 'W':
1217
case 'e':
1218
case 'E':
1219
return parseTokenOneOrTwoDigits;
1220
case 'Do':
1221
return strict ? config._locale._ordinalParse : config._locale._ordinalParseLenient;
1222
default :
1223
a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i'));
1224
return a;
1225
}
1226
}
1227
1228
function utcOffsetFromString(string) {
1229
string = string || '';
1230
var possibleTzMatches = (string.match(parseTokenTimezone) || []),
1231
tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
1232
parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
1233
minutes = +(parts[1] * 60) + toInt(parts[2]);
1234
1235
return parts[0] === '+' ? minutes : -minutes;
1236
}
1237
1238
// function to convert string input to date
1239
function addTimeToArrayFromToken(token, input, config) {
1240
var a, datePartArray = config._a;
1241
1242
switch (token) {
1243
// QUARTER
1244
case 'Q':
1245
if (input != null) {
1246
datePartArray[MONTH] = (toInt(input) - 1) * 3;
1247
}
1248
break;
1249
// MONTH
1250
case 'M' : // fall through to MM
1251
case 'MM' :
1252
if (input != null) {
1253
datePartArray[MONTH] = toInt(input) - 1;
1254
}
1255
break;
1256
case 'MMM' : // fall through to MMMM
1257
case 'MMMM' :
1258
a = config._locale.monthsParse(input, token, config._strict);
1259
// if we didn't find a month name, mark the date as invalid.
1260
if (a != null) {
1261
datePartArray[MONTH] = a;
1262
} else {
1263
config._pf.invalidMonth = input;
1264
}
1265
break;
1266
// DAY OF MONTH
1267
case 'D' : // fall through to DD
1268
case 'DD' :
1269
if (input != null) {
1270
datePartArray[DATE] = toInt(input);
1271
}
1272
break;
1273
case 'Do' :
1274
if (input != null) {
1275
datePartArray[DATE] = toInt(parseInt(
1276
input.match(/\d{1,2}/)[0], 10));
1277
}
1278
break;
1279
// DAY OF YEAR
1280
case 'DDD' : // fall through to DDDD
1281
case 'DDDD' :
1282
if (input != null) {
1283
config._dayOfYear = toInt(input);
1284
}
1285
1286
break;
1287
// YEAR
1288
case 'YY' :
1289
datePartArray[YEAR] = moment.parseTwoDigitYear(input);
1290
break;
1291
case 'YYYY' :
1292
case 'YYYYY' :
1293
case 'YYYYYY' :
1294
datePartArray[YEAR] = toInt(input);
1295
break;
1296
// AM / PM
1297
case 'a' : // fall through to A
1298
case 'A' :
1299
config._meridiem = input;
1300
// config._isPm = config._locale.isPM(input);
1301
break;
1302
// HOUR
1303
case 'h' : // fall through to hh
1304
case 'hh' :
1305
config._pf.bigHour = true;
1306
/* falls through */
1307
case 'H' : // fall through to HH
1308
case 'HH' :
1309
datePartArray[HOUR] = toInt(input);
1310
break;
1311
// MINUTE
1312
case 'm' : // fall through to mm
1313
case 'mm' :
1314
datePartArray[MINUTE] = toInt(input);
1315
break;
1316
// SECOND
1317
case 's' : // fall through to ss
1318
case 'ss' :
1319
datePartArray[SECOND] = toInt(input);
1320
break;
1321
// MILLISECOND
1322
case 'S' :
1323
case 'SS' :
1324
case 'SSS' :
1325
case 'SSSS' :
1326
datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000);
1327
break;
1328
// UNIX OFFSET (MILLISECONDS)
1329
case 'x':
1330
config._d = new Date(toInt(input));
1331
break;
1332
// UNIX TIMESTAMP WITH MS
1333
case 'X':
1334
config._d = new Date(parseFloat(input) * 1000);
1335
break;
1336
// TIMEZONE
1337
case 'Z' : // fall through to ZZ
1338
case 'ZZ' :
1339
config._useUTC = true;
1340
config._tzm = utcOffsetFromString(input);
1341
break;
1342
// WEEKDAY - human
1343
case 'dd':
1344
case 'ddd':
1345
case 'dddd':
1346
a = config._locale.weekdaysParse(input);
1347
// if we didn't get a weekday name, mark the date as invalid
1348
if (a != null) {
1349
config._w = config._w || {};
1350
config._w['d'] = a;
1351
} else {
1352
config._pf.invalidWeekday = input;
1353
}
1354
break;
1355
// WEEK, WEEK DAY - numeric
1356
case 'w':
1357
case 'ww':
1358
case 'W':
1359
case 'WW':
1360
case 'd':
1361
case 'e':
1362
case 'E':
1363
token = token.substr(0, 1);
1364
/* falls through */
1365
case 'gggg':
1366
case 'GGGG':
1367
case 'GGGGG':
1368
token = token.substr(0, 2);
1369
if (input) {
1370
config._w = config._w || {};
1371
config._w[token] = toInt(input);
1372
}
1373
break;
1374
case 'gg':
1375
case 'GG':
1376
config._w = config._w || {};
1377
config._w[token] = moment.parseTwoDigitYear(input);
1378
}
1379
}
1380
1381
function dayOfYearFromWeekInfo(config) {
1382
var w, weekYear, week, weekday, dow, doy, temp;
1383
1384
w = config._w;
1385
if (w.GG != null || w.W != null || w.E != null) {
1386
dow = 1;
1387
doy = 4;
1388
1389
// TODO: We need to take the current isoWeekYear, but that depends on
1390
// how we interpret now (local, utc, fixed offset). So create
1391
// a now version of current config (take local/utc/offset flags, and
1392
// create now).
1393
weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year);
1394
week = dfl(w.W, 1);
1395
weekday = dfl(w.E, 1);
1396
} else {
1397
dow = config._locale._week.dow;
1398
doy = config._locale._week.doy;
1399
1400
weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);
1401
week = dfl(w.w, 1);
1402
1403
if (w.d != null) {
1404
// weekday -- low day numbers are considered next week
1405
weekday = w.d;
1406
if (weekday < dow) {
1407
++week;
1408
}
1409
} else if (w.e != null) {
1410
// local weekday -- counting starts from begining of week
1411
weekday = w.e + dow;
1412
} else {
1413
// default to begining of week
1414
weekday = dow;
1415
}
1416
}
1417
temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);
1418
1419
config._a[YEAR] = temp.year;
1420
config._dayOfYear = temp.dayOfYear;
1421
}
1422
1423
// convert an array to a date.
1424
// the array should mirror the parameters below
1425
// note: all values past the year are optional and will default to the lowest possible value.
1426
// [year, month, day , hour, minute, second, millisecond]
1427
function dateFromConfig(config) {
1428
var i, date, input = [], currentDate, yearToUse;
1429
1430
if (config._d) {
1431
return;
1432
}
1433
1434
currentDate = currentDateArray(config);
1435
1436
//compute day of the year from weeks and weekdays
1437
if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
1438
dayOfYearFromWeekInfo(config);
1439
}
1440
1441
//if the day of the year is set, figure out what it is
1442
if (config._dayOfYear) {
1443
yearToUse = dfl(config._a[YEAR], currentDate[YEAR]);
1444
1445
if (config._dayOfYear > daysInYear(yearToUse)) {
1446
config._pf._overflowDayOfYear = true;
1447
}
1448
1449
date = makeUTCDate(yearToUse, 0, config._dayOfYear);
1450
config._a[MONTH] = date.getUTCMonth();
1451
config._a[DATE] = date.getUTCDate();
1452
}
1453
1454
// Default to current date.
1455
// * if no year, month, day of month are given, default to today
1456
// * if day of month is given, default month and year
1457
// * if month is given, default only year
1458
// * if year is given, don't default anything
1459
for (i = 0; i < 3 && config._a[i] == null; ++i) {
1460
config._a[i] = input[i] = currentDate[i];
1461
}
1462
1463
// Zero out whatever was not defaulted, including time
1464
for (; i < 7; i++) {
1465
config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
1466
}
1467
1468
// Check for 24:00:00.000
1469
if (config._a[HOUR] === 24 &&
1470
config._a[MINUTE] === 0 &&
1471
config._a[SECOND] === 0 &&
1472
config._a[MILLISECOND] === 0) {
1473
config._nextDay = true;
1474
config._a[HOUR] = 0;
1475
}
1476
1477
config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input);
1478
// Apply timezone offset from input. The actual utcOffset can be changed
1479
// with parseZone.
1480
if (config._tzm != null) {
1481
config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
1482
}
1483
1484
if (config._nextDay) {
1485
config._a[HOUR] = 24;
1486
}
1487
}
1488
1489
function dateFromObject(config) {
1490
var normalizedInput;
1491
1492
if (config._d) {
1493
return;
1494
}
1495
1496
normalizedInput = normalizeObjectUnits(config._i);
1497
config._a = [
1498
normalizedInput.year,
1499
normalizedInput.month,
1500
normalizedInput.day || normalizedInput.date,
1501
normalizedInput.hour,
1502
normalizedInput.minute,
1503
normalizedInput.second,
1504
normalizedInput.millisecond
1505
];
1506
1507
dateFromConfig(config);
1508
}
1509
1510
function currentDateArray(config) {
1511
var now = new Date();
1512
if (config._useUTC) {
1513
return [
1514
now.getUTCFullYear(),
1515
now.getUTCMonth(),
1516
now.getUTCDate()
1517
];
1518
} else {
1519
return [now.getFullYear(), now.getMonth(), now.getDate()];
1520
}
1521
}
1522
1523
// date from string and format string
1524
function makeDateFromStringAndFormat(config) {
1525
if (config._f === moment.ISO_8601) {
1526
parseISO(config);
1527
return;
1528
}
1529
1530
config._a = [];
1531
config._pf.empty = true;
1532
1533
// This array is used to make a Date, either with `new Date` or `Date.UTC`
1534
var string = '' + config._i,
1535
i, parsedInput, tokens, token, skipped,
1536
stringLength = string.length,
1537
totalParsedInputLength = 0;
1538
1539
tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
1540
1541
for (i = 0; i < tokens.length; i++) {
1542
token = tokens[i];
1543
parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
1544
if (parsedInput) {
1545
skipped = string.substr(0, string.indexOf(parsedInput));
1546
if (skipped.length > 0) {
1547
config._pf.unusedInput.push(skipped);
1548
}
1549
string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
1550
totalParsedInputLength += parsedInput.length;
1551
}
1552
// don't parse if it's not a known token
1553
if (formatTokenFunctions[token]) {
1554
if (parsedInput) {
1555
config._pf.empty = false;
1556
}
1557
else {
1558
config._pf.unusedTokens.push(token);
1559
}
1560
addTimeToArrayFromToken(token, parsedInput, config);
1561
}
1562
else if (config._strict && !parsedInput) {
1563
config._pf.unusedTokens.push(token);
1564
}
1565
}
1566
1567
// add remaining unparsed input length to the string
1568
config._pf.charsLeftOver = stringLength - totalParsedInputLength;
1569
if (string.length > 0) {
1570
config._pf.unusedInput.push(string);
1571
}
1572
1573
// clear _12h flag if hour is <= 12
1574
if (config._pf.bigHour === true && config._a[HOUR] <= 12) {
1575
config._pf.bigHour = undefined;
1576
}
1577
// handle meridiem
1578
config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR],
1579
config._meridiem);
1580
dateFromConfig(config);
1581
checkOverflow(config);
1582
}
1583
1584
function unescapeFormat(s) {
1585
return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
1586
return p1 || p2 || p3 || p4;
1587
});
1588
}
1589
1590
// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
1591
function regexpEscape(s) {
1592
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
1593
}
1594
1595
// date from string and array of format strings
1596
function makeDateFromStringAndArray(config) {
1597
var tempConfig,
1598
bestMoment,
1599
1600
scoreToBeat,
1601
i,
1602
currentScore;
1603
1604
if (config._f.length === 0) {
1605
config._pf.invalidFormat = true;
1606
config._d = new Date(NaN);
1607
return;
1608
}
1609
1610
for (i = 0; i < config._f.length; i++) {
1611
currentScore = 0;
1612
tempConfig = copyConfig({}, config);
1613
if (config._useUTC != null) {
1614
tempConfig._useUTC = config._useUTC;
1615
}
1616
tempConfig._pf = defaultParsingFlags();
1617
tempConfig._f = config._f[i];
1618
makeDateFromStringAndFormat(tempConfig);
1619
1620
if (!isValid(tempConfig)) {
1621
continue;
1622
}
1623
1624
// if there is any input that was not parsed add a penalty for that format
1625
currentScore += tempConfig._pf.charsLeftOver;
1626
1627
//or tokens
1628
currentScore += tempConfig._pf.unusedTokens.length * 10;
1629
1630
tempConfig._pf.score = currentScore;
1631
1632
if (scoreToBeat == null || currentScore < scoreToBeat) {
1633
scoreToBeat = currentScore;
1634
bestMoment = tempConfig;
1635
}
1636
}
1637
1638
extend(config, bestMoment || tempConfig);
1639
}
1640
1641
// date from iso format
1642
function parseISO(config) {
1643
var i, l,
1644
string = config._i,
1645
match = isoRegex.exec(string);
1646
1647
if (match) {
1648
config._pf.iso = true;
1649
for (i = 0, l = isoDates.length; i < l; i++) {
1650
if (isoDates[i][1].exec(string)) {
1651
// match[5] should be 'T' or undefined
1652
config._f = isoDates[i][0] + (match[6] || ' ');
1653
break;
1654
}
1655
}
1656
for (i = 0, l = isoTimes.length; i < l; i++) {
1657
if (isoTimes[i][1].exec(string)) {
1658
config._f += isoTimes[i][0];
1659
break;
1660
}
1661
}
1662
if (string.match(parseTokenTimezone)) {
1663
config._f += 'Z';
1664
}
1665
makeDateFromStringAndFormat(config);
1666
} else {
1667
config._isValid = false;
1668
}
1669
}
1670
1671
// date from iso format or fallback
1672
function makeDateFromString(config) {
1673
parseISO(config);
1674
if (config._isValid === false) {
1675
delete config._isValid;
1676
moment.createFromInputFallback(config);
1677
}
1678
}
1679
1680
function map(arr, fn) {
1681
var res = [], i;
1682
for (i = 0; i < arr.length; ++i) {
1683
res.push(fn(arr[i], i));
1684
}
1685
return res;
1686
}
1687
1688
function makeDateFromInput(config) {
1689
var input = config._i, matched;
1690
if (input === undefined) {
1691
config._d = new Date();
1692
} else if (isDate(input)) {
1693
config._d = new Date(+input);
1694
} else if ((matched = aspNetJsonRegex.exec(input)) !== null) {
1695
config._d = new Date(+matched[1]);
1696
} else if (typeof input === 'string') {
1697
makeDateFromString(config);
1698
} else if (isArray(input)) {
1699
config._a = map(input.slice(0), function (obj) {
1700
return parseInt(obj, 10);
1701
});
1702
dateFromConfig(config);
1703
} else if (typeof(input) === 'object') {
1704
dateFromObject(config);
1705
} else if (typeof(input) === 'number') {
1706
// from milliseconds
1707
config._d = new Date(input);
1708
} else {
1709
moment.createFromInputFallback(config);
1710
}
1711
}
1712
1713
function makeDate(y, m, d, h, M, s, ms) {
1714
//can't just apply() to create a date:
1715
//http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
1716
var date = new Date(y, m, d, h, M, s, ms);
1717
1718
//the date constructor doesn't accept years < 1970
1719
if (y < 1970) {
1720
date.setFullYear(y);
1721
}
1722
return date;
1723
}
1724
1725
function makeUTCDate(y) {
1726
var date = new Date(Date.UTC.apply(null, arguments));
1727
if (y < 1970) {
1728
date.setUTCFullYear(y);
1729
}
1730
return date;
1731
}
1732
1733
function parseWeekday(input, locale) {
1734
if (typeof input === 'string') {
1735
if (!isNaN(input)) {
1736
input = parseInt(input, 10);
1737
}
1738
else {
1739
input = locale.weekdaysParse(input);
1740
if (typeof input !== 'number') {
1741
return null;
1742
}
1743
}
1744
}
1745
return input;
1746
}
1747
1748
/************************************
1749
Relative Time
1750
************************************/
1751
1752
1753
// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
1754
function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
1755
return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
1756
}
1757
1758
function relativeTime(posNegDuration, withoutSuffix, locale) {
1759
var duration = moment.duration(posNegDuration).abs(),
1760
seconds = round(duration.as('s')),
1761
minutes = round(duration.as('m')),
1762
hours = round(duration.as('h')),
1763
days = round(duration.as('d')),
1764
months = round(duration.as('M')),
1765
years = round(duration.as('y')),
1766
1767
args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
1768
minutes === 1 && ['m'] ||
1769
minutes < relativeTimeThresholds.m && ['mm', minutes] ||
1770
hours === 1 && ['h'] ||
1771
hours < relativeTimeThresholds.h && ['hh', hours] ||
1772
days === 1 && ['d'] ||
1773
days < relativeTimeThresholds.d && ['dd', days] ||
1774
months === 1 && ['M'] ||
1775
months < relativeTimeThresholds.M && ['MM', months] ||
1776
years === 1 && ['y'] || ['yy', years];
1777
1778
args[2] = withoutSuffix;
1779
args[3] = +posNegDuration > 0;
1780
args[4] = locale;
1781
return substituteTimeAgo.apply({}, args);
1782
}
1783
1784
1785
/************************************
1786
Week of Year
1787
************************************/
1788
1789
1790
// firstDayOfWeek 0 = sun, 6 = sat
1791
// the day of the week that starts the week
1792
// (usually sunday or monday)
1793
// firstDayOfWeekOfYear 0 = sun, 6 = sat
1794
// the first week is the week that contains the first
1795
// of this day of the week
1796
// (eg. ISO weeks use thursday (4))
1797
function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
1798
var end = firstDayOfWeekOfYear - firstDayOfWeek,
1799
daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
1800
adjustedMoment;
1801
1802
1803
if (daysToDayOfWeek > end) {
1804
daysToDayOfWeek -= 7;
1805
}
1806
1807
if (daysToDayOfWeek < end - 7) {
1808
daysToDayOfWeek += 7;
1809
}
1810
1811
adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd');
1812
return {
1813
week: Math.ceil(adjustedMoment.dayOfYear() / 7),
1814
year: adjustedMoment.year()
1815
};
1816
}
1817
1818
//http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
1819
function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
1820
var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear;
1821
1822
d = d === 0 ? 7 : d;
1823
weekday = weekday != null ? weekday : firstDayOfWeek;
1824
daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);
1825
dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;
1826
1827
return {
1828
year: dayOfYear > 0 ? year : year - 1,
1829
dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
1830
};
1831
}
1832
1833
/************************************
1834
Top Level Functions
1835
************************************/
1836
1837
function makeMoment(config) {
1838
var input = config._i,
1839
format = config._f,
1840
res;
1841
1842
config._locale = config._locale || moment.localeData(config._l);
1843
1844
if (input === null || (format === undefined && input === '')) {
1845
return moment.invalid({nullInput: true});
1846
}
1847
1848
if (typeof input === 'string') {
1849
config._i = input = config._locale.preparse(input);
1850
}
1851
1852
if (moment.isMoment(input)) {
1853
return new Moment(input, true);
1854
} else if (format) {
1855
if (isArray(format)) {
1856
makeDateFromStringAndArray(config);
1857
} else {
1858
makeDateFromStringAndFormat(config);
1859
}
1860
} else {
1861
makeDateFromInput(config);
1862
}
1863
1864
res = new Moment(config);
1865
if (res._nextDay) {
1866
// Adding is smart enough around DST
1867
res.add(1, 'd');
1868
res._nextDay = undefined;
1869
}
1870
1871
return res;
1872
}
1873
1874
moment = function (input, format, locale, strict) {
1875
var c;
1876
1877
if (typeof(locale) === 'boolean') {
1878
strict = locale;
1879
locale = undefined;
1880
}
1881
// object construction must be done this way.
1882
// https://github.com/moment/moment/issues/1423
1883
c = {};
1884
c._isAMomentObject = true;
1885
c._i = input;
1886
c._f = format;
1887
c._l = locale;
1888
c._strict = strict;
1889
c._isUTC = false;
1890
c._pf = defaultParsingFlags();
1891
1892
return makeMoment(c);
1893
};
1894
1895
moment.suppressDeprecationWarnings = false;
1896
1897
moment.createFromInputFallback = deprecate(
1898
'moment construction falls back to js Date. This is ' +
1899
'discouraged and will be removed in upcoming major ' +
1900
'release. Please refer to ' +
1901
'https://github.com/moment/moment/issues/1407 for more info.',
1902
function (config) {
1903
config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
1904
}
1905
);
1906
1907
// Pick a moment m from moments so that m[fn](other) is true for all
1908
// other. This relies on the function fn to be transitive.
1909
//
1910
// moments should either be an array of moment objects or an array, whose
1911
// first element is an array of moment objects.
1912
function pickBy(fn, moments) {
1913
var res, i;
1914
if (moments.length === 1 && isArray(moments[0])) {
1915
moments = moments[0];
1916
}
1917
if (!moments.length) {
1918
return moment();
1919
}
1920
res = moments[0];
1921
for (i = 1; i < moments.length; ++i) {
1922
if (moments[i][fn](res)) {
1923
res = moments[i];
1924
}
1925
}
1926
return res;
1927
}
1928
1929
moment.min = function () {
1930
var args = [].slice.call(arguments, 0);
1931
1932
return pickBy('isBefore', args);
1933
};
1934
1935
moment.max = function () {
1936
var args = [].slice.call(arguments, 0);
1937
1938
return pickBy('isAfter', args);
1939
};
1940
1941
// creating with utc
1942
moment.utc = function (input, format, locale, strict) {
1943
var c;
1944
1945
if (typeof(locale) === 'boolean') {
1946
strict = locale;
1947
locale = undefined;
1948
}
1949
// object construction must be done this way.
1950
// https://github.com/moment/moment/issues/1423
1951
c = {};
1952
c._isAMomentObject = true;
1953
c._useUTC = true;
1954
c._isUTC = true;
1955
c._l = locale;
1956
c._i = input;
1957
c._f = format;
1958
c._strict = strict;
1959
c._pf = defaultParsingFlags();
1960
1961
return makeMoment(c).utc();
1962
};
1963
1964
// creating with unix timestamp (in seconds)
1965
moment.unix = function (input) {
1966
return moment(input * 1000);
1967
};
1968
1969
// duration
1970
moment.duration = function (input, key) {
1971
var duration = input,
1972
// matching against regexp is expensive, do it on demand
1973
match = null,
1974
sign,
1975
ret,
1976
parseIso,
1977
diffRes;
1978
1979
if (moment.isDuration(input)) {
1980
duration = {
1981
ms: input._milliseconds,
1982
d: input._days,
1983
M: input._months
1984
};
1985
} else if (typeof input === 'number') {
1986
duration = {};
1987
if (key) {
1988
duration[key] = input;
1989
} else {
1990
duration.milliseconds = input;
1991
}
1992
} else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
1993
sign = (match[1] === '-') ? -1 : 1;
1994
duration = {
1995
y: 0,
1996
d: toInt(match[DATE]) * sign,
1997
h: toInt(match[HOUR]) * sign,
1998
m: toInt(match[MINUTE]) * sign,
1999
s: toInt(match[SECOND]) * sign,
2000
ms: toInt(match[MILLISECOND]) * sign
2001
};
2002
} else if (!!(match = isoDurationRegex.exec(input))) {
2003
sign = (match[1] === '-') ? -1 : 1;
2004
parseIso = function (inp) {
2005
// We'd normally use ~~inp for this, but unfortunately it also
2006
// converts floats to ints.
2007
// inp may be undefined, so careful calling replace on it.
2008
var res = inp && parseFloat(inp.replace(',', '.'));
2009
// apply sign while we're at it
2010
return (isNaN(res) ? 0 : res) * sign;
2011
};
2012
duration = {
2013
y: parseIso(match[2]),
2014
M: parseIso(match[3]),
2015
d: parseIso(match[4]),
2016
h: parseIso(match[5]),
2017
m: parseIso(match[6]),
2018
s: parseIso(match[7]),
2019
w: parseIso(match[8])
2020
};
2021
} else if (duration == null) {// checks for null or undefined
2022
duration = {};
2023
} else if (typeof duration === 'object' &&
2024
('from' in duration || 'to' in duration)) {
2025
diffRes = momentsDifference(moment(duration.from), moment(duration.to));
2026
2027
duration = {};
2028
duration.ms = diffRes.milliseconds;
2029
duration.M = diffRes.months;
2030
}
2031
2032
ret = new Duration(duration);
2033
2034
if (moment.isDuration(input) && hasOwnProp(input, '_locale')) {
2035
ret._locale = input._locale;
2036
}
2037
2038
return ret;
2039
};
2040
2041
// version number
2042
moment.version = VERSION;
2043
2044
// default format
2045
moment.defaultFormat = isoFormat;
2046
2047
// constant that refers to the ISO standard
2048
moment.ISO_8601 = function () {};
2049
2050
// Plugins that add properties should also add the key here (null value),
2051
// so we can properly clone ourselves.
2052
moment.momentProperties = momentProperties;
2053
2054
// This function will be called whenever a moment is mutated.
2055
// It is intended to keep the offset in sync with the timezone.
2056
moment.updateOffset = function () {};
2057
2058
// This function allows you to set a threshold for relative time strings
2059
moment.relativeTimeThreshold = function (threshold, limit) {
2060
if (relativeTimeThresholds[threshold] === undefined) {
2061
return false;
2062
}
2063
if (limit === undefined) {
2064
return relativeTimeThresholds[threshold];
2065
}
2066
relativeTimeThresholds[threshold] = limit;
2067
return true;
2068
};
2069
2070
moment.lang = deprecate(
2071
'moment.lang is deprecated. Use moment.locale instead.',
2072
function (key, value) {
2073
return moment.locale(key, value);
2074
}
2075
);
2076
2077
// This function will load locale and then set the global locale. If
2078
// no arguments are passed in, it will simply return the current global
2079
// locale key.
2080
moment.locale = function (key, values) {
2081
var data;
2082
if (key) {
2083
if (typeof(values) !== 'undefined') {
2084
data = moment.defineLocale(key, values);
2085
}
2086
else {
2087
data = moment.localeData(key);
2088
}
2089
2090
if (data) {
2091
moment.duration._locale = moment._locale = data;
2092
}
2093
}
2094
2095
return moment._locale._abbr;
2096
};
2097
2098
moment.defineLocale = function (name, values) {
2099
if (values !== null) {
2100
values.abbr = name;
2101
if (!locales[name]) {
2102
locales[name] = new Locale();
2103
}
2104
locales[name].set(values);
2105
2106
// backwards compat for now: also set the locale
2107
moment.locale(name);
2108
2109
return locales[name];
2110
} else {
2111
// useful for testing
2112
delete locales[name];
2113
return null;
2114
}
2115
};
2116
2117
moment.langData = deprecate(
2118
'moment.langData is deprecated. Use moment.localeData instead.',
2119
function (key) {
2120
return moment.localeData(key);
2121
}
2122
);
2123
2124
// returns locale data
2125
moment.localeData = function (key) {
2126
var locale;
2127
2128
if (key && key._locale && key._locale._abbr) {
2129
key = key._locale._abbr;
2130
}
2131
2132
if (!key) {
2133
return moment._locale;
2134
}
2135
2136
if (!isArray(key)) {
2137
//short-circuit everything else
2138
locale = loadLocale(key);
2139
if (locale) {
2140
return locale;
2141
}
2142
key = [key];
2143
}
2144
2145
return chooseLocale(key);
2146
};
2147
2148
// compare moment object
2149
moment.isMoment = function (obj) {
2150
return obj instanceof Moment ||
2151
(obj != null && hasOwnProp(obj, '_isAMomentObject'));
2152
};
2153
2154
// for typechecking Duration objects
2155
moment.isDuration = function (obj) {
2156
return obj instanceof Duration;
2157
};
2158
2159
for (i = lists.length - 1; i >= 0; --i) {
2160
makeList(lists[i]);
2161
}
2162
2163
moment.normalizeUnits = function (units) {
2164
return normalizeUnits(units);
2165
};
2166
2167
moment.invalid = function (flags) {
2168
var m = moment.utc(NaN);
2169
if (flags != null) {
2170
extend(m._pf, flags);
2171
}
2172
else {
2173
m._pf.userInvalidated = true;
2174
}
2175
2176
return m;
2177
};
2178
2179
moment.parseZone = function () {
2180
return moment.apply(null, arguments).parseZone();
2181
};
2182
2183
moment.parseTwoDigitYear = function (input) {
2184
return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
2185
};
2186
2187
moment.isDate = isDate;
2188
2189
/************************************
2190
Moment Prototype
2191
************************************/
2192
2193
2194
extend(moment.fn = Moment.prototype, {
2195
2196
clone : function () {
2197
return moment(this);
2198
},
2199
2200
valueOf : function () {
2201
return +this._d - ((this._offset || 0) * 60000);
2202
},
2203
2204
unix : function () {
2205
return Math.floor(+this / 1000);
2206
},
2207
2208
toString : function () {
2209
return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
2210
},
2211
2212
toDate : function () {
2213
return this._offset ? new Date(+this) : this._d;
2214
},
2215
2216
toISOString : function () {
2217
var m = moment(this).utc();
2218
if (0 < m.year() && m.year() <= 9999) {
2219
if ('function' === typeof Date.prototype.toISOString) {
2220
// native implementation is ~50x faster, use it when we can
2221
return this.toDate().toISOString();
2222
} else {
2223
return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
2224
}
2225
} else {
2226
return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
2227
}
2228
},
2229
2230
toArray : function () {
2231
var m = this;
2232
return [
2233
m.year(),
2234
m.month(),
2235
m.date(),
2236
m.hours(),
2237
m.minutes(),
2238
m.seconds(),
2239
m.milliseconds()
2240
];
2241
},
2242
2243
isValid : function () {
2244
return isValid(this);
2245
},
2246
2247
isDSTShifted : function () {
2248
if (this._a) {
2249
return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
2250
}
2251
2252
return false;
2253
},
2254
2255
parsingFlags : function () {
2256
return extend({}, this._pf);
2257
},
2258
2259
invalidAt: function () {
2260
return this._pf.overflow;
2261
},
2262
2263
utc : function (keepLocalTime) {
2264
return this.utcOffset(0, keepLocalTime);
2265
},
2266
2267
local : function (keepLocalTime) {
2268
if (this._isUTC) {
2269
this.utcOffset(0, keepLocalTime);
2270
this._isUTC = false;
2271
2272
if (keepLocalTime) {
2273
this.subtract(this._dateUtcOffset(), 'm');
2274
}
2275
}
2276
return this;
2277
},
2278
2279
format : function (inputString) {
2280
var output = formatMoment(this, inputString || moment.defaultFormat);
2281
return this.localeData().postformat(output);
2282
},
2283
2284
add : createAdder(1, 'add'),
2285
2286
subtract : createAdder(-1, 'subtract'),
2287
2288
diff : function (input, units, asFloat) {
2289
var that = makeAs(input, this),
2290
zoneDiff = (that.utcOffset() - this.utcOffset()) * 6e4,
2291
anchor, diff, output, daysAdjust;
2292
2293
units = normalizeUnits(units);
2294
2295
if (units === 'year' || units === 'month' || units === 'quarter') {
2296
output = monthDiff(this, that);
2297
if (units === 'quarter') {
2298
output = output / 3;
2299
} else if (units === 'year') {
2300
output = output / 12;
2301
}
2302
} else {
2303
diff = this - that;
2304
output = units === 'second' ? diff / 1e3 : // 1000
2305
units === 'minute' ? diff / 6e4 : // 1000 * 60
2306
units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
2307
units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
2308
units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
2309
diff;
2310
}
2311
return asFloat ? output : absRound(output);
2312
},
2313
2314
from : function (time, withoutSuffix) {
2315
return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
2316
},
2317
2318
fromNow : function (withoutSuffix) {
2319
return this.from(moment(), withoutSuffix);
2320
},
2321
2322
calendar : function (time) {
2323
// We want to compare the start of today, vs this.
2324
// Getting start-of-today depends on whether we're locat/utc/offset
2325
// or not.
2326
var now = time || moment(),
2327
sod = makeAs(now, this).startOf('day'),
2328
diff = this.diff(sod, 'days', true),
2329
format = diff < -6 ? 'sameElse' :
2330
diff < -1 ? 'lastWeek' :
2331
diff < 0 ? 'lastDay' :
2332
diff < 1 ? 'sameDay' :
2333
diff < 2 ? 'nextDay' :
2334
diff < 7 ? 'nextWeek' : 'sameElse';
2335
return this.format(this.localeData().calendar(format, this, moment(now)));
2336
},
2337
2338
isLeapYear : function () {
2339
return isLeapYear(this.year());
2340
},
2341
2342
isDST : function () {
2343
return (this.utcOffset() > this.clone().month(0).utcOffset() ||
2344
this.utcOffset() > this.clone().month(5).utcOffset());
2345
},
2346
2347
day : function (input) {
2348
var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
2349
if (input != null) {
2350
input = parseWeekday(input, this.localeData());
2351
return this.add(input - day, 'd');
2352
} else {
2353
return day;
2354
}
2355
},
2356
2357
month : makeAccessor('Month', true),
2358
2359
startOf : function (units) {
2360
units = normalizeUnits(units);
2361
// the following switch intentionally omits break keywords
2362
// to utilize falling through the cases.
2363
switch (units) {
2364
case 'year':
2365
this.month(0);
2366
/* falls through */
2367
case 'quarter':
2368
case 'month':
2369
this.date(1);
2370
/* falls through */
2371
case 'week':
2372
case 'isoWeek':
2373
case 'day':
2374
this.hours(0);
2375
/* falls through */
2376
case 'hour':
2377
this.minutes(0);
2378
/* falls through */
2379
case 'minute':
2380
this.seconds(0);
2381
/* falls through */
2382
case 'second':
2383
this.milliseconds(0);
2384
/* falls through */
2385
}
2386
2387
// weeks are a special case
2388
if (units === 'week') {
2389
this.weekday(0);
2390
} else if (units === 'isoWeek') {
2391
this.isoWeekday(1);
2392
}
2393
2394
// quarters are also special
2395
if (units === 'quarter') {
2396
this.month(Math.floor(this.month() / 3) * 3);
2397
}
2398
2399
return this;
2400
},
2401
2402
endOf: function (units) {
2403
units = normalizeUnits(units);
2404
if (units === undefined || units === 'millisecond') {
2405
return this;
2406
}
2407
return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
2408
},
2409
2410
isAfter: function (input, units) {
2411
var inputMs;
2412
units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
2413
if (units === 'millisecond') {
2414
input = moment.isMoment(input) ? input : moment(input);
2415
return +this > +input;
2416
} else {
2417
inputMs = moment.isMoment(input) ? +input : +moment(input);
2418
return inputMs < +this.clone().startOf(units);
2419
}
2420
},
2421
2422
isBefore: function (input, units) {
2423
var inputMs;
2424
units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
2425
if (units === 'millisecond') {
2426
input = moment.isMoment(input) ? input : moment(input);
2427
return +this < +input;
2428
} else {
2429
inputMs = moment.isMoment(input) ? +input : +moment(input);
2430
return +this.clone().endOf(units) < inputMs;
2431
}
2432
},
2433
2434
isBetween: function (from, to, units) {
2435
return this.isAfter(from, units) && this.isBefore(to, units);
2436
},
2437
2438
isSame: function (input, units) {
2439
var inputMs;
2440
units = normalizeUnits(units || 'millisecond');
2441
if (units === 'millisecond') {
2442
input = moment.isMoment(input) ? input : moment(input);
2443
return +this === +input;
2444
} else {
2445
inputMs = +moment(input);
2446
return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));
2447
}
2448
},
2449
2450
min: deprecate(
2451
'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
2452
function (other) {
2453
other = moment.apply(null, arguments);
2454
return other < this ? this : other;
2455
}
2456
),
2457
2458
max: deprecate(
2459
'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
2460
function (other) {
2461
other = moment.apply(null, arguments);
2462
return other > this ? this : other;
2463
}
2464
),
2465
2466
zone : deprecate(
2467
'moment().zone is deprecated, use moment().utcOffset instead. ' +
2468
'https://github.com/moment/moment/issues/1779',
2469
function (input, keepLocalTime) {
2470
if (input != null) {
2471
if (typeof input !== 'string') {
2472
input = -input;
2473
}
2474
2475
this.utcOffset(input, keepLocalTime);
2476
2477
return this;
2478
} else {
2479
return -this.utcOffset();
2480
}
2481
}
2482
),
2483
2484
// keepLocalTime = true means only change the timezone, without
2485
// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
2486
// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
2487
// +0200, so we adjust the time as needed, to be valid.
2488
//
2489
// Keeping the time actually adds/subtracts (one hour)
2490
// from the actual represented time. That is why we call updateOffset
2491
// a second time. In case it wants us to change the offset again
2492
// _changeInProgress == true case, then we have to adjust, because
2493
// there is no such time in the given timezone.
2494
utcOffset : function (input, keepLocalTime) {
2495
var offset = this._offset || 0,
2496
localAdjust;
2497
if (input != null) {
2498
if (typeof input === 'string') {
2499
input = utcOffsetFromString(input);
2500
}
2501
if (Math.abs(input) < 16) {
2502
input = input * 60;
2503
}
2504
if (!this._isUTC && keepLocalTime) {
2505
localAdjust = this._dateUtcOffset();
2506
}
2507
this._offset = input;
2508
this._isUTC = true;
2509
if (localAdjust != null) {
2510
this.add(localAdjust, 'm');
2511
}
2512
if (offset !== input) {
2513
if (!keepLocalTime || this._changeInProgress) {
2514
addOrSubtractDurationFromMoment(this,
2515
moment.duration(input - offset, 'm'), 1, false);
2516
} else if (!this._changeInProgress) {
2517
this._changeInProgress = true;
2518
moment.updateOffset(this, true);
2519
this._changeInProgress = null;
2520
}
2521
}
2522
2523
return this;
2524
} else {
2525
return this._isUTC ? offset : this._dateUtcOffset();
2526
}
2527
},
2528
2529
isLocal : function () {
2530
return !this._isUTC;
2531
},
2532
2533
isUtcOffset : function () {
2534
return this._isUTC;
2535
},
2536
2537
isUtc : function () {
2538
return this._isUTC && this._offset === 0;
2539
},
2540
2541
zoneAbbr : function () {
2542
return this._isUTC ? 'UTC' : '';
2543
},
2544
2545
zoneName : function () {
2546
return this._isUTC ? 'Coordinated Universal Time' : '';
2547
},
2548
2549
parseZone : function () {
2550
if (this._tzm) {
2551
this.utcOffset(this._tzm);
2552
} else if (typeof this._i === 'string') {
2553
this.utcOffset(utcOffsetFromString(this._i));
2554
}
2555
return this;
2556
},
2557
2558
hasAlignedHourOffset : function (input) {
2559
if (!input) {
2560
input = 0;
2561
}
2562
else {
2563
input = moment(input).utcOffset();
2564
}
2565
2566
return (this.utcOffset() - input) % 60 === 0;
2567
},
2568
2569
daysInMonth : function () {
2570
return daysInMonth(this.year(), this.month());
2571
},
2572
2573
dayOfYear : function (input) {
2574
var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
2575
return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
2576
},
2577
2578
quarter : function (input) {
2579
return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
2580
},
2581
2582
weekYear : function (input) {
2583
var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
2584
return input == null ? year : this.add((input - year), 'y');
2585
},
2586
2587
isoWeekYear : function (input) {
2588
var year = weekOfYear(this, 1, 4).year;
2589
return input == null ? year : this.add((input - year), 'y');
2590
},
2591
2592
week : function (input) {
2593
var week = this.localeData().week(this);
2594
return input == null ? week : this.add((input - week) * 7, 'd');
2595
},
2596
2597
isoWeek : function (input) {
2598
var week = weekOfYear(this, 1, 4).week;
2599
return input == null ? week : this.add((input - week) * 7, 'd');
2600
},
2601
2602
weekday : function (input) {
2603
var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
2604
return input == null ? weekday : this.add(input - weekday, 'd');
2605
},
2606
2607
isoWeekday : function (input) {
2608
// behaves the same as moment#day except
2609
// as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
2610
// as a setter, sunday should belong to the previous week.
2611
return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
2612
},
2613
2614
isoWeeksInYear : function () {
2615
return weeksInYear(this.year(), 1, 4);
2616
},
2617
2618
weeksInYear : function () {
2619
var weekInfo = this.localeData()._week;
2620
return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
2621
},
2622
2623
get : function (units) {
2624
units = normalizeUnits(units);
2625
return this[units]();
2626
},
2627
2628
set : function (units, value) {
2629
var unit;
2630
if (typeof units === 'object') {
2631
for (unit in units) {
2632
this.set(unit, units[unit]);
2633
}
2634
}
2635
else {
2636
units = normalizeUnits(units);
2637
if (typeof this[units] === 'function') {
2638
this[units](value);
2639
}
2640
}
2641
return this;
2642
},
2643
2644
// If passed a locale key, it will set the locale for this
2645
// instance. Otherwise, it will return the locale configuration
2646
// variables for this instance.
2647
locale : function (key) {
2648
var newLocaleData;
2649
2650
if (key === undefined) {
2651
return this._locale._abbr;
2652
} else {
2653
newLocaleData = moment.localeData(key);
2654
if (newLocaleData != null) {
2655
this._locale = newLocaleData;
2656
}
2657
return this;
2658
}
2659
},
2660
2661
lang : deprecate(
2662
'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
2663
function (key) {
2664
if (key === undefined) {
2665
return this.localeData();
2666
} else {
2667
return this.locale(key);
2668
}
2669
}
2670
),
2671
2672
localeData : function () {
2673
return this._locale;
2674
},
2675
2676
_dateUtcOffset : function () {
2677
// On Firefox.24 Date#getTimezoneOffset returns a floating point.
2678
// https://github.com/moment/moment/pull/1871
2679
return -Math.round(this._d.getTimezoneOffset() / 15) * 15;
2680
}
2681
2682
});
2683
2684
function rawMonthSetter(mom, value) {
2685
var dayOfMonth;
2686
2687
// TODO: Move this out of here!
2688
if (typeof value === 'string') {
2689
value = mom.localeData().monthsParse(value);
2690
// TODO: Another silent failure?
2691
if (typeof value !== 'number') {
2692
return mom;
2693
}
2694
}
2695
2696
dayOfMonth = Math.min(mom.date(),
2697
daysInMonth(mom.year(), value));
2698
mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
2699
return mom;
2700
}
2701
2702
function rawGetter(mom, unit) {
2703
return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
2704
}
2705
2706
function rawSetter(mom, unit, value) {
2707
if (unit === 'Month') {
2708
return rawMonthSetter(mom, value);
2709
} else {
2710
return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
2711
}
2712
}
2713
2714
function makeAccessor(unit, keepTime) {
2715
return function (value) {
2716
if (value != null) {
2717
rawSetter(this, unit, value);
2718
moment.updateOffset(this, keepTime);
2719
return this;
2720
} else {
2721
return rawGetter(this, unit);
2722
}
2723
};
2724
}
2725
2726
moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false);
2727
moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false);
2728
moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false);
2729
// Setting the hour should keep the time, because the user explicitly
2730
// specified which hour he wants. So trying to maintain the same hour (in
2731
// a new timezone) makes sense. Adding/subtracting hours does not follow
2732
// this rule.
2733
moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);
2734
// moment.fn.month is defined separately
2735
moment.fn.date = makeAccessor('Date', true);
2736
moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true));
2737
moment.fn.year = makeAccessor('FullYear', true);
2738
moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true));
2739
2740
// add plural methods
2741
moment.fn.days = moment.fn.day;
2742
moment.fn.months = moment.fn.month;
2743
moment.fn.weeks = moment.fn.week;
2744
moment.fn.isoWeeks = moment.fn.isoWeek;
2745
moment.fn.quarters = moment.fn.quarter;
2746
2747
// add aliased format methods
2748
moment.fn.toJSON = moment.fn.toISOString;
2749
2750
// alias isUtc for dev-friendliness
2751
moment.fn.isUTC = moment.fn.isUtc;
2752
2753
/************************************
2754
Duration Prototype
2755
************************************/
2756
2757
2758
function daysToYears (days) {
2759
// 400 years have 146097 days (taking into account leap year rules)
2760
return days * 400 / 146097;
2761
}
2762
2763
function yearsToDays (years) {
2764
// years * 365 + absRound(years / 4) -
2765
// absRound(years / 100) + absRound(years / 400);
2766
return years * 146097 / 400;
2767
}
2768
2769
extend(moment.duration.fn = Duration.prototype, {
2770
2771
_bubble : function () {
2772
var milliseconds = this._milliseconds,
2773
days = this._days,
2774
months = this._months,
2775
data = this._data,
2776
seconds, minutes, hours, years = 0;
2777
2778
// The following code bubbles up values, see the tests for
2779
// examples of what that means.
2780
data.milliseconds = milliseconds % 1000;
2781
2782
seconds = absRound(milliseconds / 1000);
2783
data.seconds = seconds % 60;
2784
2785
minutes = absRound(seconds / 60);
2786
data.minutes = minutes % 60;
2787
2788
hours = absRound(minutes / 60);
2789
data.hours = hours % 24;
2790
2791
days += absRound(hours / 24);
2792
2793
// Accurately convert days to years, assume start from year 0.
2794
years = absRound(daysToYears(days));
2795
days -= absRound(yearsToDays(years));
2796
2797
// 30 days to a month
2798
// TODO (iskren): Use anchor date (like 1st Jan) to compute this.
2799
months += absRound(days / 30);
2800
days %= 30;
2801
2802
// 12 months -> 1 year
2803
years += absRound(months / 12);
2804
months %= 12;
2805
2806
data.days = days;
2807
data.months = months;
2808
data.years = years;
2809
},
2810
2811
abs : function () {
2812
this._milliseconds = Math.abs(this._milliseconds);
2813
this._days = Math.abs(this._days);
2814
this._months = Math.abs(this._months);
2815
2816
this._data.milliseconds = Math.abs(this._data.milliseconds);
2817
this._data.seconds = Math.abs(this._data.seconds);
2818
this._data.minutes = Math.abs(this._data.minutes);
2819
this._data.hours = Math.abs(this._data.hours);
2820
this._data.months = Math.abs(this._data.months);
2821
this._data.years = Math.abs(this._data.years);
2822
2823
return this;
2824
},
2825
2826
weeks : function () {
2827
return absRound(this.days() / 7);
2828
},
2829
2830
valueOf : function () {
2831
return this._milliseconds +
2832
this._days * 864e5 +
2833
(this._months % 12) * 2592e6 +
2834
toInt(this._months / 12) * 31536e6;
2835
},
2836
2837
humanize : function (withSuffix) {
2838
var output = relativeTime(this, !withSuffix, this.localeData());
2839
2840
if (withSuffix) {
2841
output = this.localeData().pastFuture(+this, output);
2842
}
2843
2844
return this.localeData().postformat(output);
2845
},
2846
2847
add : function (input, val) {
2848
// supports only 2.0-style add(1, 's') or add(moment)
2849
var dur = moment.duration(input, val);
2850
2851
this._milliseconds += dur._milliseconds;
2852
this._days += dur._days;
2853
this._months += dur._months;
2854
2855
this._bubble();
2856
2857
return this;
2858
},
2859
2860
subtract : function (input, val) {
2861
var dur = moment.duration(input, val);
2862
2863
this._milliseconds -= dur._milliseconds;
2864
this._days -= dur._days;
2865
this._months -= dur._months;
2866
2867
this._bubble();
2868
2869
return this;
2870
},
2871
2872
get : function (units) {
2873
units = normalizeUnits(units);
2874
return this[units.toLowerCase() + 's']();
2875
},
2876
2877
as : function (units) {
2878
var days, months;
2879
units = normalizeUnits(units);
2880
2881
if (units === 'month' || units === 'year') {
2882
days = this._days + this._milliseconds / 864e5;
2883
months = this._months + daysToYears(days) * 12;
2884
return units === 'month' ? months : months / 12;
2885
} else {
2886
// handle milliseconds separately because of floating point math errors (issue #1867)
2887
days = this._days + Math.round(yearsToDays(this._months / 12));
2888
switch (units) {
2889
case 'week': return days / 7 + this._milliseconds / 6048e5;
2890
case 'day': return days + this._milliseconds / 864e5;
2891
case 'hour': return days * 24 + this._milliseconds / 36e5;
2892
case 'minute': return days * 24 * 60 + this._milliseconds / 6e4;
2893
case 'second': return days * 24 * 60 * 60 + this._milliseconds / 1000;
2894
// Math.floor prevents floating point math errors here
2895
case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds;
2896
default: throw new Error('Unknown unit ' + units);
2897
}
2898
}
2899
},
2900
2901
lang : moment.fn.lang,
2902
locale : moment.fn.locale,
2903
2904
toIsoString : deprecate(
2905
'toIsoString() is deprecated. Please use toISOString() instead ' +
2906
'(notice the capitals)',
2907
function () {
2908
return this.toISOString();
2909
}
2910
),
2911
2912
toISOString : function () {
2913
// inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
2914
var years = Math.abs(this.years()),
2915
months = Math.abs(this.months()),
2916
days = Math.abs(this.days()),
2917
hours = Math.abs(this.hours()),
2918
minutes = Math.abs(this.minutes()),
2919
seconds = Math.abs(this.seconds() + this.milliseconds() / 1000);
2920
2921
if (!this.asSeconds()) {
2922
// this is the same as C#'s (Noda) and python (isodate)...
2923
// but not other JS (goog.date)
2924
return 'P0D';
2925
}
2926
2927
return (this.asSeconds() < 0 ? '-' : '') +
2928
'P' +
2929
(years ? years + 'Y' : '') +
2930
(months ? months + 'M' : '') +
2931
(days ? days + 'D' : '') +
2932
((hours || minutes || seconds) ? 'T' : '') +
2933
(hours ? hours + 'H' : '') +
2934
(minutes ? minutes + 'M' : '') +
2935
(seconds ? seconds + 'S' : '');
2936
},
2937
2938
localeData : function () {
2939
return this._locale;
2940
},
2941
2942
toJSON : function () {
2943
return this.toISOString();
2944
}
2945
});
2946
2947
moment.duration.fn.toString = moment.duration.fn.toISOString;
2948
2949
function makeDurationGetter(name) {
2950
moment.duration.fn[name] = function () {
2951
return this._data[name];
2952
};
2953
}
2954
2955
for (i in unitMillisecondFactors) {
2956
if (hasOwnProp(unitMillisecondFactors, i)) {
2957
makeDurationGetter(i.toLowerCase());
2958
}
2959
}
2960
2961
moment.duration.fn.asMilliseconds = function () {
2962
return this.as('ms');
2963
};
2964
moment.duration.fn.asSeconds = function () {
2965
return this.as('s');
2966
};
2967
moment.duration.fn.asMinutes = function () {
2968
return this.as('m');
2969
};
2970
moment.duration.fn.asHours = function () {
2971
return this.as('h');
2972
};
2973
moment.duration.fn.asDays = function () {
2974
return this.as('d');
2975
};
2976
moment.duration.fn.asWeeks = function () {
2977
return this.as('weeks');
2978
};
2979
moment.duration.fn.asMonths = function () {
2980
return this.as('M');
2981
};
2982
moment.duration.fn.asYears = function () {
2983
return this.as('y');
2984
};
2985
2986
/************************************
2987
Default Locale
2988
************************************/
2989
2990
2991
// Set default locale, other locale will inherit from English.
2992
moment.locale('en', {
2993
ordinalParse: /\d{1,2}(th|st|nd|rd)/,
2994
ordinal : function (number) {
2995
var b = number % 10,
2996
output = (toInt(number % 100 / 10) === 1) ? 'th' :
2997
(b === 1) ? 'st' :
2998
(b === 2) ? 'nd' :
2999
(b === 3) ? 'rd' : 'th';
3000
return number + output;
3001
}
3002
});
3003
3004
/* EMBED_LOCALES */
3005
3006
/************************************
3007
Exposing Moment
3008
************************************/
3009
3010
function makeGlobal(shouldDeprecate) {
3011
/*global ender:false */
3012
if (typeof ender !== 'undefined') {
3013
return;
3014
}
3015
oldGlobalMoment = globalScope.moment;
3016
if (shouldDeprecate) {
3017
globalScope.moment = deprecate(
3018
'Accessing Moment through the global scope is ' +
3019
'deprecated, and will be removed in an upcoming ' +
3020
'release.',
3021
moment);
3022
} else {
3023
globalScope.moment = moment;
3024
}
3025
}
3026
3027
// CommonJS module is defined
3028
if (hasModule) {
3029
module.exports = moment;
3030
} else if (typeof define === 'function' && define.amd) {
3031
define(function (require, exports, module) {
3032
if (module.config && module.config() && module.config().noGlobal === true) {
3033
// release the global variable
3034
globalScope.moment = oldGlobalMoment;
3035
}
3036
3037
return moment;
3038
});
3039
makeGlobal(true);
3040
} else {
3041
makeGlobal();
3042
}
3043
}).call(this);
3044
3045