//! moment.js
-//! version : 2.17.1
+//! version : 2.18.1
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com
return true;
}
+function isUndefined(input) {
+ return input === void 0;
+}
+
function isNumber(input) {
return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
}
userInvalidated : false,
iso : false,
parsedDateParts : [],
- meridiem : null
+ meridiem : null,
+ rfc2822 : false,
+ weekdayMismatch : false
};
}
return m;
}
-function isUndefined(input) {
- return input === void 0;
-}
-
// Plugins that add properties should also add the key here (null value),
// so we can properly clone ourselves.
var momentProperties = hooks.momentProperties = [];
}
if (momentProperties.length > 0) {
- for (i in momentProperties) {
+ for (i = 0; i < momentProperties.length; i++) {
prop = momentProperties[i];
val = from[prop];
if (!isUndefined(val)) {
}
this._config = config;
// Lenient ordinal parsing accepts just a number in addition to
- // number + (possibly) stuff coming from _ordinalParseLenient.
- this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\d{1,2}/).source);
+ // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
+ // TODO: Remove "ordinalParse" fallback in next major release.
+ this._dayOfMonthOrdinalParseLenient = new RegExp(
+ (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
+ '|' + (/\d{1,2}/).source);
}
function mergeConfigs(parentConfig, childConfig) {
}
var defaultOrdinal = '%d';
-var defaultOrdinalParse = /\d{1,2}/;
+var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
function ordinal (number) {
return this._ordinal.replace('%d', number);
future : 'in %s',
past : '%s ago',
s : 'a few seconds',
+ ss : '%d seconds',
m : 'a minute',
mm : '%d minutes',
h : 'an hour',
return function (mom) {
var output = '', i;
for (i = 0; i < length; i++) {
- output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
+ output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
}
return output;
};
var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
function localeMonths (m, format) {
if (!m) {
- return this._months;
+ return isArray(this._months) ? this._months :
+ this._months['standalone'];
}
return isArray(this._months) ? this._months[m.month()] :
this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
function localeMonthsShort (m, format) {
if (!m) {
- return this._monthsShort;
+ return isArray(this._monthsShort) ? this._monthsShort :
+ this._monthsShort['standalone'];
}
return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
}
function createDate (y, m, d, h, M, s, ms) {
- //can't just apply() to create a date:
- //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
+ // can't just apply() to create a date:
+ // https://stackoverflow.com/q/181348
var date = new Date(y, m, d, h, M, s, ms);
- //the date constructor remaps years 0-99 to 1900-1999
+ // the date constructor remaps years 0-99 to 1900-1999
if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
date.setFullYear(y);
}
function createUTCDate (y) {
var date = new Date(Date.UTC.apply(null, arguments));
- //the Date.UTC function remaps years 0-99 to 1900-1999
+ // the Date.UTC function remaps years 0-99 to 1900-1999
if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
date.setUTCFullYear(y);
}
return -fwdlw + fwd - 1;
}
-//http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
+// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
var localWeekday = (7 + weekday - dow) % 7,
weekOffset = firstWeekOffset(year, dow, doy),
var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
function localeWeekdays (m, format) {
if (!m) {
- return this._weekdays;
+ return isArray(this._weekdays) ? this._weekdays :
+ this._weekdays['standalone'];
}
return isArray(this._weekdays) ? this._weekdays[m.day()] :
this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
addRegexToken('A', matchMeridiem);
addRegexToken('H', match1to2);
addRegexToken('h', match1to2);
+addRegexToken('k', match1to2);
addRegexToken('HH', match1to2, match2);
addRegexToken('hh', match1to2, match2);
+addRegexToken('kk', match1to2, match2);
addRegexToken('hmm', match3to4);
addRegexToken('hmmss', match5to6);
addRegexToken('Hmmss', match5to6);
addParseToken(['H', 'HH'], HOUR);
+addParseToken(['k', 'kk'], function (input, array, config) {
+ var kInput = toInt(input);
+ array[HOUR] = kInput === 24 ? 0 : kInput;
+});
addParseToken(['a', 'A'], function (input, array, config) {
config._isPm = config._locale.isPM(input);
config._meridiem = input;
longDateFormat: defaultLongDateFormat,
invalidDate: defaultInvalidDate,
ordinal: defaultOrdinal,
- ordinalParse: defaultOrdinalParse,
+ dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
relativeTime: defaultRelativeTime,
months: defaultLocaleMonths,
}
}
+// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
+var basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d?\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(?:\d\d)?\d\d\s)(\d\d:\d\d)(\:\d\d)?(\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\d{4}))$/;
+
+// date and time from ref 2822 format
+function configFromRFC2822(config) {
+ var string, match, dayFormat,
+ dateFormat, timeFormat, tzFormat;
+ var timezones = {
+ ' GMT': ' +0000',
+ ' EDT': ' -0400',
+ ' EST': ' -0500',
+ ' CDT': ' -0500',
+ ' CST': ' -0600',
+ ' MDT': ' -0600',
+ ' MST': ' -0700',
+ ' PDT': ' -0700',
+ ' PST': ' -0800'
+ };
+ var military = 'YXWVUTSRQPONZABCDEFGHIKLM';
+ var timezone, timezoneIndex;
+
+ string = config._i
+ .replace(/\([^\)]*\)|[\n\t]/g, ' ') // Remove comments and folding whitespace
+ .replace(/(\s\s+)/g, ' ') // Replace multiple-spaces with a single space
+ .replace(/^\s|\s$/g, ''); // Remove leading and trailing spaces
+ match = basicRfcRegex.exec(string);
+
+ if (match) {
+ dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';
+ dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');
+ timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');
+
+ // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
+ if (match[1]) { // day of week given
+ var momentDate = new Date(match[2]);
+ var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];
+
+ if (match[1].substr(0,3) !== momentDay) {
+ getParsingFlags(config).weekdayMismatch = true;
+ config._isValid = false;
+ return;
+ }
+ }
+
+ switch (match[5].length) {
+ case 2: // military
+ if (timezoneIndex === 0) {
+ timezone = ' +0000';
+ } else {
+ timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;
+ timezone = ((timezoneIndex < 0) ? ' -' : ' +') +
+ (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';
+ }
+ break;
+ case 4: // Zone
+ timezone = timezones[match[5]];
+ break;
+ default: // UT or +/-9999
+ timezone = timezones[' GMT'];
+ }
+ match[5] = timezone;
+ config._i = match.splice(1).join('');
+ tzFormat = ' ZZ';
+ config._f = dayFormat + dateFormat + timeFormat + tzFormat;
+ configFromStringAndFormat(config);
+ getParsingFlags(config).rfc2822 = true;
+ } else {
+ config._isValid = false;
+ }
+}
+
// date from iso format or fallback
function configFromString(config) {
var matched = aspNetJsonRegex.exec(config._i);
configFromISO(config);
if (config._isValid === false) {
delete config._isValid;
- hooks.createFromInputFallback(config);
+ } else {
+ return;
+ }
+
+ configFromRFC2822(config);
+ if (config._isValid === false) {
+ delete config._isValid;
+ } else {
+ return;
}
+
+ // Final attempt, use Input Fallback
+ hooks.createFromInputFallback(config);
}
hooks.createFromInputFallback = deprecate(
- 'value provided is not in a recognized ISO format. moment construction falls back to js Date(), ' +
- 'which is not reliable across all browsers and versions. Non ISO date formats are ' +
+ 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
+ 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
'discouraged and will be removed in an upcoming major release. Please refer to ' +
'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
function (config) {
}
//if the day of the year is set, figure out what it is
- if (config._dayOfYear) {
+ if (config._dayOfYear != null) {
yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
- if (config._dayOfYear > daysInYear(yearToUse)) {
+ if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
getParsingFlags(config)._overflowDayOfYear = true;
}
// constant that refers to the ISO standard
hooks.ISO_8601 = function () {};
+// constant that refers to the RFC 2822 form
+hooks.RFC_2822 = function () {};
+
// date from string and format string
function configFromStringAndFormat(config) {
// TODO: Move this to another part of the creation flow to prevent circular deps
configFromISO(config);
return;
}
-
+ if (config._f === hooks.RFC_2822) {
+ configFromRFC2822(config);
+ return;
+ }
config._a = [];
getParsingFlags(config).empty = true;
function configFromInput(config) {
var input = config._i;
- if (input === undefined) {
+ if (isUndefined(input)) {
config._d = new Date(hooks.now());
} else if (isDate(input)) {
config._d = new Date(input.valueOf());
return parseInt(obj, 10);
});
configFromArray(config);
- } else if (typeof(input) === 'object') {
+ } else if (isObject(input)) {
configFromObject(config);
} else if (isNumber(input)) {
// from milliseconds
return Date.now ? Date.now() : +(new Date());
};
+var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
+
+function isDurationValid(m) {
+ for (var key in m) {
+ if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
+ return false;
+ }
+ }
+
+ var unitHasDecimal = false;
+ for (var i = 0; i < ordering.length; ++i) {
+ if (m[ordering[i]]) {
+ if (unitHasDecimal) {
+ return false; // only allow non-integers for smallest unit
+ }
+ if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
+ unitHasDecimal = true;
+ }
+ }
+ }
+
+ return true;
+}
+
+function isValid$1() {
+ return this._isValid;
+}
+
+function createInvalid$1() {
+ return createDuration(NaN);
+}
+
function Duration (duration) {
var normalizedInput = normalizeObjectUnits(duration),
years = normalizedInput.year || 0,
seconds = normalizedInput.second || 0,
milliseconds = normalizedInput.millisecond || 0;
+ this._isValid = isDurationValid(normalizedInput);
+
// representation for dateAddRemove
this._milliseconds = +milliseconds +
seconds * 1e3 + // 1000
// a second time. In case it wants us to change the offset again
// _changeInProgress == true case, then we have to adjust, because
// there is no such time in the given timezone.
-function getSetOffset (input, keepLocalTime) {
+function getSetOffset (input, keepLocalTime, keepMinutes) {
var offset = this._offset || 0,
localAdjust;
if (!this.isValid()) {
if (input === null) {
return this;
}
- } else if (Math.abs(input) < 16) {
+ } else if (Math.abs(input) < 16 && !keepMinutes) {
input = input * 60;
}
if (!this._isUTC && keepLocalTime) {
function setOffsetToParsedOffset () {
if (this._tzm != null) {
- this.utcOffset(this._tzm);
+ this.utcOffset(this._tzm, false, true);
} else if (typeof this._i === 'string') {
var tZone = offsetFromString(matchOffset, this._i);
if (tZone != null) {
}
createDuration.fn = Duration.prototype;
+createDuration.invalid = createInvalid$1;
function parseIso (inp, sign) {
// We'd normally use ~~inp for this, but unfortunately it also
return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
}
-function toISOString () {
+function toISOString() {
+ if (!this.isValid()) {
+ return null;
+ }
var m = this.clone().utc();
- if (0 < m.year() && m.year() <= 9999) {
- if (isFunction(Date.prototype.toISOString)) {
- // native implementation is ~50x faster, use it when we can
- return this.toDate().toISOString();
- } else {
- return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
- }
- } else {
+ if (m.year() < 0 || m.year() > 9999) {
return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
}
+ if (isFunction(Date.prototype.toISOString)) {
+ // native implementation is ~50x faster, use it when we can
+ return this.toDate().toISOString();
+ }
+ return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
}
/**
zone = 'Z';
}
var prefix = '[' + func + '("]';
- var year = (0 < this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
+ var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
var datetime = '-MM-DD[T]HH:mm:ss.SSS';
var suffix = zone + '[")]';
return this.isValid() ? this.toISOString() : null;
}
-function isValid$1 () {
+function isValid$2 () {
return isValid(this);
}
addRegexToken('D', match1to2);
addRegexToken('DD', match1to2, match2);
addRegexToken('Do', function (isStrict, locale) {
- return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;
+ // TODO: Remove "ordinalParse" fallback in next major release.
+ return isStrict ?
+ (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :
+ locale._dayOfMonthOrdinalParseLenient;
});
addParseToken(['D', 'DD'], DATE);
proto.isSame = isSame;
proto.isSameOrAfter = isSameOrAfter;
proto.isSameOrBefore = isSameOrBefore;
-proto.isValid = isValid$1;
+proto.isValid = isValid$2;
proto.lang = lang;
proto.locale = locale;
proto.localeData = localeData;
}
getSetGlobalLocale('en', {
- ordinalParse: /\d{1,2}(th|st|nd|rd)/,
+ dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
ordinal : function (number) {
var b = number % 10,
output = (toInt(number % 100 / 10) === 1) ? 'th' :
}
function as (units) {
+ if (!this.isValid()) {
+ return NaN;
+ }
var days;
var months;
var milliseconds = this._milliseconds;
// TODO: Use this.as('ms')?
function valueOf$1 () {
+ if (!this.isValid()) {
+ return NaN;
+ }
return (
this._milliseconds +
this._days * 864e5 +
function get$2 (units) {
units = normalizeUnits(units);
- return this[units + 's']();
+ return this.isValid() ? this[units + 's']() : NaN;
}
function makeGetter(name) {
return function () {
- return this._data[name];
+ return this.isValid() ? this._data[name] : NaN;
};
}
var round = Math.round;
var thresholds = {
- s: 45, // seconds to minute
- m: 45, // minutes to hour
- h: 22, // hours to day
- d: 26, // days to month
- M: 11 // months to year
+ ss: 44, // a few seconds to seconds
+ s : 45, // seconds to minute
+ m : 45, // minutes to hour
+ h : 22, // hours to day
+ d : 26, // days to month
+ M : 11 // months to year
};
// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
var months = round(duration.as('M'));
var years = round(duration.as('y'));
- var a = seconds < thresholds.s && ['s', seconds] ||
- minutes <= 1 && ['m'] ||
- minutes < thresholds.m && ['mm', minutes] ||
- hours <= 1 && ['h'] ||
- hours < thresholds.h && ['hh', hours] ||
- days <= 1 && ['d'] ||
- days < thresholds.d && ['dd', days] ||
- months <= 1 && ['M'] ||
- months < thresholds.M && ['MM', months] ||
- years <= 1 && ['y'] || ['yy', years];
+ var a = seconds <= thresholds.ss && ['s', seconds] ||
+ seconds < thresholds.s && ['ss', seconds] ||
+ minutes <= 1 && ['m'] ||
+ minutes < thresholds.m && ['mm', minutes] ||
+ hours <= 1 && ['h'] ||
+ hours < thresholds.h && ['hh', hours] ||
+ days <= 1 && ['d'] ||
+ days < thresholds.d && ['dd', days] ||
+ months <= 1 && ['M'] ||
+ months < thresholds.M && ['MM', months] ||
+ years <= 1 && ['y'] || ['yy', years];
a[2] = withoutSuffix;
a[3] = +posNegDuration > 0;
return thresholds[threshold];
}
thresholds[threshold] = limit;
+ if (threshold === 's') {
+ thresholds.ss = limit - 1;
+ }
return true;
}
function humanize (withSuffix) {
+ if (!this.isValid()) {
+ return this.localeData().invalidDate();
+ }
+
var locale = this.localeData();
var output = relativeTime$1(this, !withSuffix, locale);
// This is because there is no context-free conversion between hours and days
// (think of clock changes)
// and also not between days and months (28-31 days per month)
+ if (!this.isValid()) {
+ return this.localeData().invalidDate();
+ }
+
var seconds = abs$1(this._milliseconds) / 1000;
var days = abs$1(this._days);
var months = abs$1(this._months);
var proto$2 = Duration.prototype;
+proto$2.isValid = isValid$1;
proto$2.abs = abs;
proto$2.add = add$1;
proto$2.subtract = subtract$1;
// Side effect imports
-hooks.version = '2.17.1';
+hooks.version = '2.18.1';
setHookCallback(createLocal);