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