aboutsummaryrefslogtreecommitdiffstats
path: root/library/moment/moment.js
diff options
context:
space:
mode:
Diffstat (limited to 'library/moment/moment.js')
-rw-r--r--library/moment/moment.js1189
1 files changed, 841 insertions, 348 deletions
diff --git a/library/moment/moment.js b/library/moment/moment.js
index 23cd3ede1..b5f0b3644 100644
--- a/library/moment/moment.js
+++ b/library/moment/moment.js
@@ -1,10 +1,10 @@
//! moment.js
-//! version : 2.10.6
+//! version : 2.12.0
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com
-(function (global, factory) {
+;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
global.moment = factory()
@@ -23,7 +23,7 @@
}
function isArray(input) {
- return Object.prototype.toString.call(input) === '[object Array]';
+ return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
}
function isDate(input) {
@@ -121,39 +121,45 @@
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 = utils_hooks__hooks.momentProperties = [];
function copyConfig(to, from) {
var i, prop, val;
- if (typeof from._isAMomentObject !== 'undefined') {
+ if (!isUndefined(from._isAMomentObject)) {
to._isAMomentObject = from._isAMomentObject;
}
- if (typeof from._i !== 'undefined') {
+ if (!isUndefined(from._i)) {
to._i = from._i;
}
- if (typeof from._f !== 'undefined') {
+ if (!isUndefined(from._f)) {
to._f = from._f;
}
- if (typeof from._l !== 'undefined') {
+ if (!isUndefined(from._l)) {
to._l = from._l;
}
- if (typeof from._strict !== 'undefined') {
+ if (!isUndefined(from._strict)) {
to._strict = from._strict;
}
- if (typeof from._tzm !== 'undefined') {
+ if (!isUndefined(from._tzm)) {
to._tzm = from._tzm;
}
- if (typeof from._isUTC !== 'undefined') {
+ if (!isUndefined(from._isUTC)) {
to._isUTC = from._isUTC;
}
- if (typeof from._offset !== 'undefined') {
+ if (!isUndefined(from._offset)) {
to._offset = from._offset;
}
- if (typeof from._pf !== 'undefined') {
+ if (!isUndefined(from._pf)) {
to._pf = getParsingFlags(from);
}
- if (typeof from._locale !== 'undefined') {
+ if (!isUndefined(from._locale)) {
to._locale = from._locale;
}
@@ -161,7 +167,7 @@
for (i in momentProperties) {
prop = momentProperties[i];
val = from[prop];
- if (typeof val !== 'undefined') {
+ if (!isUndefined(val)) {
to[prop] = val;
}
}
@@ -208,6 +214,7 @@
return value;
}
+ // compare two arrays, return the number of differences
function compareArrays(array1, array2, dontConvert) {
var len = Math.min(array1.length, array2.length),
lengthDiff = Math.abs(array1.length - array2.length),
@@ -222,9 +229,85 @@
return diffs + lengthDiff;
}
- function Locale() {
+ function warn(msg) {
+ if (utils_hooks__hooks.suppressDeprecationWarnings === false &&
+ (typeof console !== 'undefined') && console.warn) {
+ console.warn('Deprecation warning: ' + msg);
+ }
+ }
+
+ function deprecate(msg, fn) {
+ var firstTime = true;
+
+ return extend(function () {
+ if (firstTime) {
+ warn(msg + '\nArguments: ' + Array.prototype.slice.call(arguments).join(', ') + '\n' + (new Error()).stack);
+ firstTime = false;
+ }
+ return fn.apply(this, arguments);
+ }, fn);
+ }
+
+ var deprecations = {};
+
+ function deprecateSimple(name, msg) {
+ if (!deprecations[name]) {
+ warn(msg);
+ deprecations[name] = true;
+ }
+ }
+
+ utils_hooks__hooks.suppressDeprecationWarnings = false;
+
+ function isFunction(input) {
+ return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
+ }
+
+ function isObject(input) {
+ return Object.prototype.toString.call(input) === '[object Object]';
+ }
+
+ function locale_set__set (config) {
+ var prop, i;
+ for (i in config) {
+ prop = config[i];
+ if (isFunction(prop)) {
+ this[i] = prop;
+ } else {
+ this['_' + i] = prop;
+ }
+ }
+ 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);
+ }
+
+ function mergeConfigs(parentConfig, childConfig) {
+ var res = extend({}, parentConfig), prop;
+ for (prop in childConfig) {
+ if (hasOwnProp(childConfig, prop)) {
+ if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
+ res[prop] = {};
+ extend(res[prop], parentConfig[prop]);
+ extend(res[prop], childConfig[prop]);
+ } else if (childConfig[prop] != null) {
+ res[prop] = childConfig[prop];
+ } else {
+ delete res[prop];
+ }
+ }
+ }
+ return res;
+ }
+
+ function Locale(config) {
+ if (config != null) {
+ this.set(config);
+ }
}
+ // internal storage for locale config files
var locales = {};
var globalLocale;
@@ -262,7 +345,7 @@
function loadLocale(name) {
var oldLocale = null;
// TODO: Find a better way to register and load all the locales in Node
- if (!locales[name] && typeof module !== 'undefined' &&
+ if (!locales[name] && (typeof module !== 'undefined') &&
module && module.exports) {
try {
oldLocale = globalLocale._abbr;
@@ -281,7 +364,7 @@
function locale_locales__getSetGlobalLocale (key, values) {
var data;
if (key) {
- if (typeof values === 'undefined') {
+ if (isUndefined(values)) {
data = locale_locales__getLocale(key);
}
else {
@@ -297,11 +380,25 @@
return globalLocale._abbr;
}
- function defineLocale (name, values) {
- if (values !== null) {
- values.abbr = name;
- locales[name] = locales[name] || new Locale();
- locales[name].set(values);
+ function defineLocale (name, config) {
+ if (config !== null) {
+ config.abbr = name;
+ if (locales[name] != null) {
+ deprecateSimple('defineLocaleOverride',
+ 'use moment.updateLocale(localeName, config) to change ' +
+ 'an existing locale. moment.defineLocale(localeName, ' +
+ 'config) should only be used for creating a new locale');
+ config = mergeConfigs(locales[name]._config, config);
+ } else if (config.parentLocale != null) {
+ if (locales[config.parentLocale] != null) {
+ config = mergeConfigs(locales[config.parentLocale]._config, config);
+ } else {
+ // treat as if there is no base config
+ deprecateSimple('parentLocaleUndefined',
+ 'specified parentLocale is not defined yet');
+ }
+ }
+ locales[name] = new Locale(config);
// backwards compat for now: also set the locale
locale_locales__getSetGlobalLocale(name);
@@ -314,6 +411,31 @@
}
}
+ function updateLocale(name, config) {
+ if (config != null) {
+ var locale;
+ if (locales[name] != null) {
+ config = mergeConfigs(locales[name]._config, config);
+ }
+ locale = new Locale(config);
+ locale.parentLocale = locales[name];
+ locales[name] = locale;
+
+ // backwards compat for now: also set the locale
+ locale_locales__getSetGlobalLocale(name);
+ } else {
+ // pass null for config to unupdate, useful for tests
+ if (locales[name] != null) {
+ if (locales[name].parentLocale != null) {
+ locales[name] = locales[name].parentLocale;
+ } else if (locales[name] != null) {
+ delete locales[name];
+ }
+ }
+ }
+ return locales[name];
+ }
+
// returns locale data
function locale_locales__getLocale (key) {
var locale;
@@ -338,6 +460,10 @@
return chooseLocale(key);
}
+ function locale_locales__listLocales() {
+ return Object.keys(locales);
+ }
+
var aliases = {};
function addUnitAlias (unit, shorthand) {
@@ -379,11 +505,14 @@
}
function get_set__get (mom, unit) {
- return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
+ return mom.isValid() ?
+ mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
}
function get_set__set (mom, unit, value) {
- return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
+ if (mom.isValid()) {
+ mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
+ }
}
// MOMENTS
@@ -396,7 +525,7 @@
}
} else {
units = normalizeUnits(units);
- if (typeof this[units] === 'function') {
+ if (isFunction(this[units])) {
return this[units](value);
}
}
@@ -411,7 +540,7 @@
Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
}
- var 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,9}|x|X|zz?|ZZ?|.)/g;
+ var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
@@ -507,6 +636,8 @@
var match4 = /\d{4}/; // 0000 - 9999
var match6 = /[+-]?\d{6}/; // -999999 - 999999
var match1to2 = /\d\d?/; // 0 - 99
+ var match3to4 = /\d\d\d\d?/; // 999 - 9999
+ var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999
var match1to3 = /\d{1,3}/; // 0 - 999
var match1to4 = /\d{1,4}/; // 0 - 9999
var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999
@@ -515,23 +646,19 @@
var matchSigned = /[+-]?\d+/; // -inf - inf
var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
+ var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
// any word (or two) characters or numbers including two/three word month in arabic.
+ // includes scottish gaelic two word and hyphenated months
var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
- var regexes = {};
-
- function isFunction (sth) {
- // https://github.com/moment/moment/issues/2325
- return typeof sth === 'function' &&
- Object.prototype.toString.call(sth) === '[object Function]';
- }
+ var regexes = {};
function addRegexToken (token, regex, strictRegex) {
- regexes[token] = isFunction(regex) ? regex : function (isStrict) {
+ regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
return (isStrict && strictRegex) ? strictRegex : regex;
};
}
@@ -546,9 +673,13 @@
// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
function unescapeFormat(s) {
- return s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
+ return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
return p1 || p2 || p3 || p4;
- }).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
+ }));
+ }
+
+ function regexEscape(s) {
+ return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
var tokens = {};
@@ -588,6 +719,8 @@
var MINUTE = 4;
var SECOND = 5;
var MILLISECOND = 6;
+ var WEEK = 7;
+ var WEEKDAY = 8;
function daysInMonth(year, month) {
return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
@@ -615,8 +748,12 @@
addRegexToken('M', match1to2);
addRegexToken('MM', match1to2, match2);
- addRegexToken('MMM', matchWord);
- addRegexToken('MMMM', matchWord);
+ addRegexToken('MMM', function (isStrict, locale) {
+ return locale.monthsShortRegex(isStrict);
+ });
+ addRegexToken('MMMM', function (isStrict, locale) {
+ return locale.monthsRegex(isStrict);
+ });
addParseToken(['M', 'MM'], function (input, array) {
array[MONTH] = toInt(input) - 1;
@@ -634,14 +771,17 @@
// LOCALES
+ var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/;
var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
- function localeMonths (m) {
- return this._months[m.month()];
+ function localeMonths (m, format) {
+ return isArray(this._months) ? this._months[m.month()] :
+ this._months[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) {
- return this._monthsShort[m.month()];
+ function localeMonthsShort (m, format) {
+ return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
+ this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
}
function localeMonthsParse (monthName, format, strict) {
@@ -680,12 +820,20 @@
function setMonth (mom, value) {
var dayOfMonth;
- // TODO: Move this out of here!
+ if (!mom.isValid()) {
+ // No op
+ return mom;
+ }
+
if (typeof value === 'string') {
- value = mom.localeData().monthsParse(value);
- // TODO: Another silent failure?
- if (typeof value !== 'number') {
- return mom;
+ if (/^\d+$/.test(value)) {
+ value = toInt(value);
+ } else {
+ value = mom.localeData().monthsParse(value);
+ // TODO: Another silent failure?
+ if (typeof value !== 'number') {
+ return mom;
+ }
}
}
@@ -708,6 +856,72 @@
return daysInMonth(this.year(), this.month());
}
+ var defaultMonthsShortRegex = matchWord;
+ function monthsShortRegex (isStrict) {
+ if (this._monthsParseExact) {
+ if (!hasOwnProp(this, '_monthsRegex')) {
+ computeMonthsParse.call(this);
+ }
+ if (isStrict) {
+ return this._monthsShortStrictRegex;
+ } else {
+ return this._monthsShortRegex;
+ }
+ } else {
+ return this._monthsShortStrictRegex && isStrict ?
+ this._monthsShortStrictRegex : this._monthsShortRegex;
+ }
+ }
+
+ var defaultMonthsRegex = matchWord;
+ function monthsRegex (isStrict) {
+ if (this._monthsParseExact) {
+ if (!hasOwnProp(this, '_monthsRegex')) {
+ computeMonthsParse.call(this);
+ }
+ if (isStrict) {
+ return this._monthsStrictRegex;
+ } else {
+ return this._monthsRegex;
+ }
+ } else {
+ return this._monthsStrictRegex && isStrict ?
+ this._monthsStrictRegex : this._monthsRegex;
+ }
+ }
+
+ function computeMonthsParse () {
+ function cmpLenRev(a, b) {
+ return b.length - a.length;
+ }
+
+ var shortPieces = [], longPieces = [], mixedPieces = [],
+ i, mom;
+ for (i = 0; i < 12; i++) {
+ // make the regex if we don't have it already
+ mom = create_utc__createUTC([2000, i]);
+ shortPieces.push(this.monthsShort(mom, ''));
+ longPieces.push(this.months(mom, ''));
+ mixedPieces.push(this.months(mom, ''));
+ mixedPieces.push(this.monthsShort(mom, ''));
+ }
+ // Sorting makes sure if one month (or abbr) is a prefix of another it
+ // will match the longer piece.
+ shortPieces.sort(cmpLenRev);
+ longPieces.sort(cmpLenRev);
+ mixedPieces.sort(cmpLenRev);
+ for (i = 0; i < 12; i++) {
+ shortPieces[i] = regexEscape(shortPieces[i]);
+ longPieces[i] = regexEscape(longPieces[i]);
+ mixedPieces[i] = regexEscape(mixedPieces[i]);
+ }
+
+ this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
+ this._monthsShortRegex = this._monthsRegex;
+ this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')$', 'i');
+ this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')$', 'i');
+ }
+
function checkOverflow (m) {
var overflow;
var a = m._a;
@@ -725,6 +939,12 @@
if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
overflow = DATE;
}
+ if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
+ overflow = WEEK;
+ }
+ if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
+ overflow = WEEKDAY;
+ }
getParsingFlags(m).overflow = overflow;
}
@@ -732,51 +952,39 @@
return m;
}
- function warn(msg) {
- if (utils_hooks__hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {
- console.warn('Deprecation warning: ' + msg);
- }
- }
+ // iso 8601 regex
+ // 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)
+ var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/;
+ var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/;
- function deprecate(msg, fn) {
- var firstTime = true;
-
- return extend(function () {
- if (firstTime) {
- warn(msg + '\n' + (new Error()).stack);
- firstTime = false;
- }
- return fn.apply(this, arguments);
- }, fn);
- }
-
- var deprecations = {};
-
- function deprecateSimple(name, msg) {
- if (!deprecations[name]) {
- warn(msg);
- deprecations[name] = true;
- }
- }
-
- utils_hooks__hooks.suppressDeprecationWarnings = false;
-
- var from_string__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)?)?$/;
+ var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
var isoDates = [
- ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
- ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
- ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
- ['GGGG-[W]WW', /\d{4}-W\d{2}/],
- ['YYYY-DDD', /\d{4}-\d{3}/]
+ ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
+ ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
+ ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
+ ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
+ ['YYYY-DDD', /\d{4}-\d{3}/],
+ ['YYYY-MM', /\d{4}-\d\d/, false],
+ ['YYYYYYMMDD', /[+-]\d{10}/],
+ ['YYYYMMDD', /\d{8}/],
+ // YYYYMM is NOT allowed by the standard
+ ['GGGG[W]WWE', /\d{4}W\d{3}/],
+ ['GGGG[W]WW', /\d{4}W\d{2}/, false],
+ ['YYYYDDD', /\d{7}/]
];
// iso time formats and regexes
var isoTimes = [
- ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/],
- ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
- ['HH:mm', /(T| )\d\d:\d\d/],
- ['HH', /(T| )\d\d/]
+ ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
+ ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
+ ['HH:mm:ss', /\d\d:\d\d:\d\d/],
+ ['HH:mm', /\d\d:\d\d/],
+ ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
+ ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
+ ['HHmmss', /\d\d\d\d\d\d/],
+ ['HHmm', /\d\d\d\d/],
+ ['HH', /\d\d/]
];
var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
@@ -785,26 +993,49 @@
function configFromISO(config) {
var i, l,
string = config._i,
- match = from_string__isoRegex.exec(string);
+ match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
+ allowTime, dateFormat, timeFormat, tzFormat;
if (match) {
getParsingFlags(config).iso = true;
+
for (i = 0, l = isoDates.length; i < l; i++) {
- if (isoDates[i][1].exec(string)) {
- config._f = isoDates[i][0];
+ if (isoDates[i][1].exec(match[1])) {
+ dateFormat = isoDates[i][0];
+ allowTime = isoDates[i][2] !== false;
break;
}
}
- for (i = 0, l = isoTimes.length; i < l; i++) {
- if (isoTimes[i][1].exec(string)) {
- // match[6] should be 'T' or space
- config._f += (match[6] || ' ') + isoTimes[i][0];
- break;
+ if (dateFormat == null) {
+ config._isValid = false;
+ return;
+ }
+ if (match[3]) {
+ for (i = 0, l = isoTimes.length; i < l; i++) {
+ if (isoTimes[i][1].exec(match[3])) {
+ // match[2] should be 'T' or space
+ timeFormat = (match[2] || ' ') + isoTimes[i][0];
+ break;
+ }
}
+ if (timeFormat == null) {
+ config._isValid = false;
+ return;
+ }
+ }
+ if (!allowTime && timeFormat != null) {
+ config._isValid = false;
+ return;
}
- if (string.match(matchOffset)) {
- config._f += 'Z';
+ if (match[4]) {
+ if (tzRegex.exec(match[4])) {
+ tzFormat = 'Z';
+ } else {
+ config._isValid = false;
+ return;
+ }
}
+ config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
configFromStringAndFormat(config);
} else {
config._isValid = false;
@@ -842,8 +1073,8 @@
//http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
var date = new Date(y, m, d, h, M, s, ms);
- //the date constructor doesn't accept years < 1970
- if (y < 1970) {
+ //the date constructor remaps years 0-99 to 1900-1999
+ if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
date.setFullYear(y);
}
return date;
@@ -851,12 +1082,21 @@
function createUTCDate (y) {
var date = new Date(Date.UTC.apply(null, arguments));
- if (y < 1970) {
+
+ //the Date.UTC function remaps years 0-99 to 1900-1999
+ if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
date.setUTCFullYear(y);
}
return date;
}
+ // FORMATTING
+
+ addFormatToken('Y', 0, 0, function () {
+ var y = this.year();
+ return y <= 9999 ? '' + y : '+' + y;
+ });
+
addFormatToken(0, ['YY', 2], 0, function () {
return this.year() % 100;
});
@@ -884,6 +1124,9 @@
addParseToken('YY', function (input, array) {
array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);
});
+ addParseToken('Y', function (input, array) {
+ array[YEAR] = parseInt(input, 10);
+ });
// HELPERS
@@ -909,124 +1152,66 @@
return isLeapYear(this.year());
}
- addFormatToken('w', ['ww', 2], 'wo', 'week');
- addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
-
- // ALIASES
-
- addUnitAlias('week', 'w');
- addUnitAlias('isoWeek', 'W');
-
- // PARSING
-
- addRegexToken('w', match1to2);
- addRegexToken('ww', match1to2, match2);
- addRegexToken('W', match1to2);
- addRegexToken('WW', match1to2, match2);
-
- addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
- week[token.substr(0, 1)] = toInt(input);
- });
-
- // HELPERS
-
- // firstDayOfWeek 0 = sun, 6 = sat
- // the day of the week that starts the week
- // (usually sunday or monday)
- // firstDayOfWeekOfYear 0 = sun, 6 = sat
- // the first week is the week that contains the first
- // of this day of the week
- // (eg. ISO weeks use thursday (4))
- function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
- var end = firstDayOfWeekOfYear - firstDayOfWeek,
- daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
- adjustedMoment;
-
+ // start-of-first-week - start-of-year
+ function firstWeekOffset(year, dow, doy) {
+ var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
+ fwd = 7 + dow - doy,
+ // first-week day local weekday -- which local weekday is fwd
+ fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
- if (daysToDayOfWeek > end) {
- daysToDayOfWeek -= 7;
- }
+ return -fwdlw + fwd - 1;
+ }
- if (daysToDayOfWeek < end - 7) {
- daysToDayOfWeek += 7;
+ //http://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),
+ dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
+ resYear, resDayOfYear;
+
+ if (dayOfYear <= 0) {
+ resYear = year - 1;
+ resDayOfYear = daysInYear(resYear) + dayOfYear;
+ } else if (dayOfYear > daysInYear(year)) {
+ resYear = year + 1;
+ resDayOfYear = dayOfYear - daysInYear(year);
+ } else {
+ resYear = year;
+ resDayOfYear = dayOfYear;
}
- adjustedMoment = local__createLocal(mom).add(daysToDayOfWeek, 'd');
return {
- week: Math.ceil(adjustedMoment.dayOfYear() / 7),
- year: adjustedMoment.year()
+ year: resYear,
+ dayOfYear: resDayOfYear
};
}
- // LOCALES
-
- function localeWeek (mom) {
- return weekOfYear(mom, this._week.dow, this._week.doy).week;
- }
-
- var defaultLocaleWeek = {
- dow : 0, // Sunday is the first day of the week.
- doy : 6 // The week that contains Jan 1st is the first week of the year.
- };
-
- function localeFirstDayOfWeek () {
- return this._week.dow;
- }
-
- function localeFirstDayOfYear () {
- return this._week.doy;
- }
-
- // MOMENTS
+ function weekOfYear(mom, dow, doy) {
+ var weekOffset = firstWeekOffset(mom.year(), dow, doy),
+ week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
+ resWeek, resYear;
- function getSetWeek (input) {
- var week = this.localeData().week(this);
- return input == null ? week : this.add((input - week) * 7, 'd');
- }
-
- function getSetISOWeek (input) {
- var week = weekOfYear(this, 1, 4).week;
- return input == null ? week : this.add((input - week) * 7, 'd');
- }
-
- addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
-
- // ALIASES
-
- addUnitAlias('dayOfYear', 'DDD');
-
- // PARSING
-
- addRegexToken('DDD', match1to3);
- addRegexToken('DDDD', match3);
- addParseToken(['DDD', 'DDDD'], function (input, array, config) {
- config._dayOfYear = toInt(input);
- });
-
- // HELPERS
-
- //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
- function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
- var week1Jan = 6 + firstDayOfWeek - firstDayOfWeekOfYear, janX = createUTCDate(year, 0, 1 + week1Jan), d = janX.getUTCDay(), dayOfYear;
- if (d < firstDayOfWeek) {
- d += 7;
+ if (week < 1) {
+ resYear = mom.year() - 1;
+ resWeek = week + weeksInYear(resYear, dow, doy);
+ } else if (week > weeksInYear(mom.year(), dow, doy)) {
+ resWeek = week - weeksInYear(mom.year(), dow, doy);
+ resYear = mom.year() + 1;
+ } else {
+ resYear = mom.year();
+ resWeek = week;
}
- weekday = weekday != null ? 1 * weekday : firstDayOfWeek;
-
- dayOfYear = 1 + week1Jan + 7 * (week - 1) - d + weekday;
-
return {
- year: dayOfYear > 0 ? year : year - 1,
- dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
+ week: resWeek,
+ year: resYear
};
}
- // MOMENTS
-
- function getSetDayOfYear (input) {
- var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
- return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
+ function weeksInYear(year, dow, doy) {
+ var weekOffset = firstWeekOffset(year, dow, doy),
+ weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
+ return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
}
// Pick the first defined of two or three arguments.
@@ -1041,11 +1226,12 @@
}
function currentDateArray(config) {
- var now = new Date();
+ // hooks is actually the exported moment object
+ var nowValue = new Date(utils_hooks__hooks.now());
if (config._useUTC) {
- return [now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()];
+ return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
}
- return [now.getFullYear(), now.getMonth(), now.getDate()];
+ return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
}
// convert an array to a date.
@@ -1115,7 +1301,7 @@
}
function dayOfYearFromWeekInfo(config) {
- var w, weekYear, week, weekday, dow, doy, temp;
+ var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
w = config._w;
if (w.GG != null || w.W != null || w.E != null) {
@@ -1129,6 +1315,9 @@
weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year);
week = defaults(w.W, 1);
weekday = defaults(w.E, 1);
+ if (weekday < 1 || weekday > 7) {
+ weekdayOverflow = true;
+ }
} else {
dow = config._locale._week.dow;
doy = config._locale._week.doy;
@@ -1139,23 +1328,32 @@
if (w.d != null) {
// weekday -- low day numbers are considered next week
weekday = w.d;
- if (weekday < dow) {
- ++week;
+ if (weekday < 0 || weekday > 6) {
+ weekdayOverflow = true;
}
} else if (w.e != null) {
// local weekday -- counting starts from begining of week
weekday = w.e + dow;
+ if (w.e < 0 || w.e > 6) {
+ weekdayOverflow = true;
+ }
} else {
// default to begining of week
weekday = dow;
}
}
- temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);
-
- config._a[YEAR] = temp.year;
- config._dayOfYear = temp.dayOfYear;
+ if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
+ getParsingFlags(config)._overflowWeeks = true;
+ } else if (weekdayOverflow != null) {
+ getParsingFlags(config)._overflowWeekday = true;
+ } else {
+ temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
+ config._a[YEAR] = temp.year;
+ config._dayOfYear = temp.dayOfYear;
+ }
}
+ // constant that refers to the ISO standard
utils_hooks__hooks.ISO_8601 = function () {};
// date from string and format string
@@ -1180,6 +1378,8 @@
for (i = 0; i < tokens.length; i++) {
token = tokens[i];
parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
+ // console.log('token', token, 'parsedInput', parsedInput,
+ // 'regex', getParseRegexForToken(token, config));
if (parsedInput) {
skipped = string.substr(0, string.indexOf(parsedInput));
if (skipped.length > 0) {
@@ -1248,6 +1448,7 @@
}
}
+ // date from string and array of format strings
function configFromStringAndArray(config) {
var tempConfig,
bestMoment,
@@ -1298,7 +1499,9 @@
}
var i = normalizeObjectUnits(config._i);
- config._a = [i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond];
+ config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
+ return obj && parseInt(obj, 10);
+ });
configFromArray(config);
}
@@ -1340,13 +1543,17 @@
configFromInput(config);
}
+ if (!valid__isValid(config)) {
+ config._d = null;
+ }
+
return config;
}
function configFromInput(config) {
var input = config._i;
if (input === undefined) {
- config._d = new Date();
+ config._d = new Date(utils_hooks__hooks.now());
} else if (isDate(input)) {
config._d = new Date(+input);
} else if (typeof input === 'string') {
@@ -1390,18 +1597,26 @@
}
var prototypeMin = deprecate(
- 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
+ 'moment().min is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
function () {
var other = local__createLocal.apply(null, arguments);
- return other < this ? this : other;
+ if (this.isValid() && other.isValid()) {
+ return other < this ? this : other;
+ } else {
+ return valid__createInvalid();
+ }
}
);
var prototypeMax = deprecate(
- 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
+ 'moment().max is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
function () {
var other = local__createLocal.apply(null, arguments);
- return other > this ? this : other;
+ if (this.isValid() && other.isValid()) {
+ return other > this ? this : other;
+ } else {
+ return valid__createInvalid();
+ }
}
);
@@ -1440,6 +1655,10 @@
return pickBy('isAfter', args);
}
+ var now = function () {
+ return Date.now ? Date.now() : +(new Date());
+ };
+
function Duration (duration) {
var normalizedInput = normalizeObjectUnits(duration),
years = normalizedInput.year || 0,
@@ -1479,6 +1698,8 @@
return obj instanceof Duration;
}
+ // FORMATTING
+
function offset (token, separator) {
addFormatToken(token, 0, 0, function () {
var offset = this.utcOffset();
@@ -1496,11 +1717,11 @@
// PARSING
- addRegexToken('Z', matchOffset);
- addRegexToken('ZZ', matchOffset);
+ addRegexToken('Z', matchShortOffset);
+ addRegexToken('ZZ', matchShortOffset);
addParseToken(['Z', 'ZZ'], function (input, array, config) {
config._useUTC = true;
- config._tzm = offsetFromString(input);
+ config._tzm = offsetFromString(matchShortOffset, input);
});
// HELPERS
@@ -1510,8 +1731,8 @@
// '-1530' > ['-15', '30']
var chunkOffset = /([\+\-]|\d\d)/gi;
- function offsetFromString(string) {
- var matches = ((string || '').match(matchOffset) || []);
+ function offsetFromString(matcher, string) {
+ var matches = ((string || '').match(matcher) || []);
var chunk = matches[matches.length - 1] || [];
var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
var minutes = +(parts[1] * 60) + toInt(parts[2]);
@@ -1561,11 +1782,13 @@
function getSetOffset (input, keepLocalTime) {
var offset = this._offset || 0,
localAdjust;
+ if (!this.isValid()) {
+ return input != null ? this : NaN;
+ }
if (input != null) {
if (typeof input === 'string') {
- input = offsetFromString(input);
- }
- if (Math.abs(input) < 16) {
+ input = offsetFromString(matchShortOffset, input);
+ } else if (Math.abs(input) < 16) {
input = input * 60;
}
if (!this._isUTC && keepLocalTime) {
@@ -1625,12 +1848,15 @@
if (this._tzm) {
this.utcOffset(this._tzm);
} else if (typeof this._i === 'string') {
- this.utcOffset(offsetFromString(this._i));
+ this.utcOffset(offsetFromString(matchOffset, this._i));
}
return this;
}
function hasAlignedHourOffset (input) {
+ if (!this.isValid()) {
+ return false;
+ }
input = input ? local__createLocal(input).utcOffset() : 0;
return (this.utcOffset() - input) % 60 === 0;
@@ -1644,7 +1870,7 @@
}
function isDaylightSavingTimeShifted () {
- if (typeof this._isDSTShifted !== 'undefined') {
+ if (!isUndefined(this._isDSTShifted)) {
return this._isDSTShifted;
}
@@ -1665,22 +1891,24 @@
}
function isLocal () {
- return !this._isUTC;
+ return this.isValid() ? !this._isUTC : false;
}
function isUtcOffset () {
- return this._isUTC;
+ return this.isValid() ? this._isUTC : false;
}
function isUtc () {
- return this._isUTC && this._offset === 0;
+ return this.isValid() ? this._isUTC && this._offset === 0 : false;
}
- var aspNetRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/;
+ // ASP.NET json date format regex
+ var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/;
// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
- var create__isoRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;
+ // and further modified to allow for strings containing both week and day
+ var isoRegex = /^(-)?P(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)W)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?$/;
function create__createDuration (input, key) {
var duration = input,
@@ -1713,16 +1941,16 @@
s : toInt(match[SECOND]) * sign,
ms : toInt(match[MILLISECOND]) * sign
};
- } else if (!!(match = create__isoRegex.exec(input))) {
+ } else if (!!(match = isoRegex.exec(input))) {
sign = (match[1] === '-') ? -1 : 1;
duration = {
y : parseIso(match[2], sign),
M : parseIso(match[3], sign),
- d : parseIso(match[4], sign),
- h : parseIso(match[5], sign),
- m : parseIso(match[6], sign),
- s : parseIso(match[7], sign),
- w : parseIso(match[8], sign)
+ w : parseIso(match[4], sign),
+ d : parseIso(match[5], sign),
+ h : parseIso(match[6], sign),
+ m : parseIso(match[7], sign),
+ s : parseIso(match[8], sign)
};
} else if (duration == null) {// checks for null or undefined
duration = {};
@@ -1770,6 +1998,10 @@
function momentsDifference(base, other) {
var res;
+ if (!(base.isValid() && other.isValid())) {
+ return {milliseconds: 0, months: 0};
+ }
+
other = cloneWithOffset(other, base);
if (base.isBefore(other)) {
res = positiveMomentsDifference(base, other);
@@ -1782,6 +2014,15 @@
return res;
}
+ function absRound (number) {
+ if (number < 0) {
+ return Math.round(-1 * number) * -1;
+ } else {
+ return Math.round(number);
+ }
+ }
+
+ // TODO: remove 'name' arg after deprecation is removed
function createAdder(direction, name) {
return function (val, period) {
var dur, tmp;
@@ -1800,8 +2041,14 @@
function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) {
var milliseconds = duration._milliseconds,
- days = duration._days,
- months = duration._months;
+ days = absRound(duration._days),
+ months = absRound(duration._months);
+
+ if (!mom.isValid()) {
+ // No op
+ return;
+ }
+
updateOffset = updateOffset == null ? true : updateOffset;
if (milliseconds) {
@@ -1833,7 +2080,10 @@
diff < 1 ? 'sameDay' :
diff < 2 ? 'nextDay' :
diff < 7 ? 'nextWeek' : 'sameElse';
- return this.format(formats && formats[format] || this.localeData().calendar(format, this, local__createLocal(now)));
+
+ var output = formats && (isFunction(formats[format]) ? formats[format]() : formats[format]);
+
+ return this.format(output || this.localeData().calendar(format, this, local__createLocal(now)));
}
function clone () {
@@ -1841,26 +2091,28 @@
}
function isAfter (input, units) {
- var inputMs;
- units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
+ var localInput = isMoment(input) ? input : local__createLocal(input);
+ if (!(this.isValid() && localInput.isValid())) {
+ return false;
+ }
+ units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
if (units === 'millisecond') {
- input = isMoment(input) ? input : local__createLocal(input);
- return +this > +input;
+ return +this > +localInput;
} else {
- inputMs = isMoment(input) ? +input : +local__createLocal(input);
- return inputMs < +this.clone().startOf(units);
+ return +localInput < +this.clone().startOf(units);
}
}
function isBefore (input, units) {
- var inputMs;
- units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
+ var localInput = isMoment(input) ? input : local__createLocal(input);
+ if (!(this.isValid() && localInput.isValid())) {
+ return false;
+ }
+ units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
if (units === 'millisecond') {
- input = isMoment(input) ? input : local__createLocal(input);
- return +this < +input;
+ return +this < +localInput;
} else {
- inputMs = isMoment(input) ? +input : +local__createLocal(input);
- return +this.clone().endOf(units) < inputMs;
+ return +this.clone().endOf(units) < +localInput;
}
}
@@ -1869,22 +2121,45 @@
}
function isSame (input, units) {
- var inputMs;
+ var localInput = isMoment(input) ? input : local__createLocal(input),
+ inputMs;
+ if (!(this.isValid() && localInput.isValid())) {
+ return false;
+ }
units = normalizeUnits(units || 'millisecond');
if (units === 'millisecond') {
- input = isMoment(input) ? input : local__createLocal(input);
- return +this === +input;
+ return +this === +localInput;
} else {
- inputMs = +local__createLocal(input);
+ inputMs = +localInput;
return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));
}
}
+ function isSameOrAfter (input, units) {
+ return this.isSame(input, units) || this.isAfter(input,units);
+ }
+
+ function isSameOrBefore (input, units) {
+ return this.isSame(input, units) || this.isBefore(input,units);
+ }
+
function diff (input, units, asFloat) {
- var that = cloneWithOffset(input, this),
- zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4,
+ var that,
+ zoneDelta,
delta, output;
+ if (!this.isValid()) {
+ return NaN;
+ }
+
+ that = cloneWithOffset(input, this);
+
+ if (!that.isValid()) {
+ return NaN;
+ }
+
+ zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
+
units = normalizeUnits(units);
if (units === 'year' || units === 'month' || units === 'quarter') {
@@ -1935,7 +2210,7 @@
function moment_format__toISOString () {
var m = this.clone().utc();
if (0 < m.year() && m.year() <= 9999) {
- if ('function' === typeof Date.prototype.toISOString) {
+ if (isFunction(Date.prototype.toISOString)) {
// native implementation is ~50x faster, use it when we can
return this.toDate().toISOString();
} else {
@@ -1952,10 +2227,13 @@
}
function from (time, withoutSuffix) {
- if (!this.isValid()) {
+ if (this.isValid() &&
+ ((isMoment(time) && time.isValid()) ||
+ local__createLocal(time).isValid())) {
+ return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
+ } else {
return this.localeData().invalidDate();
}
- return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
}
function fromNow (withoutSuffix) {
@@ -1963,16 +2241,22 @@
}
function to (time, withoutSuffix) {
- if (!this.isValid()) {
+ if (this.isValid() &&
+ ((isMoment(time) && time.isValid()) ||
+ local__createLocal(time).isValid())) {
+ return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
+ } else {
return this.localeData().invalidDate();
}
- return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
}
function toNow (withoutSuffix) {
return this.to(local__createLocal(), withoutSuffix);
}
+ // If passed a locale key, it will set the locale for this
+ // instance. Otherwise, it will return the locale configuration
+ // variables for this instance.
function locale (key) {
var newLocaleData;
@@ -2083,6 +2367,11 @@
};
}
+ function toJSON () {
+ // new Date(NaN).toJSON() === null
+ return this.isValid() ? this.toISOString() : null;
+ }
+
function moment_valid__isValid () {
return valid__isValid(this);
}
@@ -2095,6 +2384,18 @@
return getParsingFlags(this).overflow;
}
+ function creationData() {
+ return {
+ input: this._i,
+ format: this._f,
+ locale: this._locale,
+ isUTC: this._isUTC,
+ strict: this._strict
+ };
+ }
+
+ // FORMATTING
+
addFormatToken(0, ['gg', 2], 0, function () {
return this.weekYear() % 100;
});
@@ -2136,22 +2437,20 @@
week[token] = utils_hooks__hooks.parseTwoDigitYear(input);
});
- // HELPERS
-
- function weeksInYear(year, dow, doy) {
- return weekOfYear(local__createLocal([year, 11, 31 + dow - doy]), dow, doy).week;
- }
-
// MOMENTS
function getSetWeekYear (input) {
- var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
- return input == null ? year : this.add((input - year), 'y');
+ return getSetWeekYearHelper.call(this,
+ input,
+ this.week(),
+ this.weekday(),
+ this.localeData()._week.dow,
+ this.localeData()._week.doy);
}
function getSetISOWeekYear (input) {
- var year = weekOfYear(this, 1, 4).year;
- return input == null ? year : this.add((input - year), 'y');
+ return getSetWeekYearHelper.call(this,
+ input, this.isoWeek(), this.isoWeekday(), 1, 4);
}
function getISOWeeksInYear () {
@@ -2163,7 +2462,32 @@
return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
}
- addFormatToken('Q', 0, 0, 'quarter');
+ function getSetWeekYearHelper(input, week, weekday, dow, doy) {
+ var weeksTarget;
+ if (input == null) {
+ return weekOfYear(this, dow, doy).year;
+ } else {
+ weeksTarget = weeksInYear(input, dow, doy);
+ if (week > weeksTarget) {
+ week = weeksTarget;
+ }
+ return setWeekAll.call(this, input, week, weekday, dow, doy);
+ }
+ }
+
+ function setWeekAll(weekYear, week, weekday, dow, doy) {
+ var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
+ date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
+
+ this.year(date.getUTCFullYear());
+ this.month(date.getUTCMonth());
+ this.date(date.getUTCDate());
+ return this;
+ }
+
+ // FORMATTING
+
+ addFormatToken('Q', 0, 'Qo', 'quarter');
// ALIASES
@@ -2182,6 +2506,62 @@
return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
}
+ // FORMATTING
+
+ addFormatToken('w', ['ww', 2], 'wo', 'week');
+ addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
+
+ // ALIASES
+
+ addUnitAlias('week', 'w');
+ addUnitAlias('isoWeek', 'W');
+
+ // PARSING
+
+ addRegexToken('w', match1to2);
+ addRegexToken('ww', match1to2, match2);
+ addRegexToken('W', match1to2);
+ addRegexToken('WW', match1to2, match2);
+
+ addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
+ week[token.substr(0, 1)] = toInt(input);
+ });
+
+ // HELPERS
+
+ // LOCALES
+
+ function localeWeek (mom) {
+ return weekOfYear(mom, this._week.dow, this._week.doy).week;
+ }
+
+ var defaultLocaleWeek = {
+ dow : 0, // Sunday is the first day of the week.
+ doy : 6 // The week that contains Jan 1st is the first week of the year.
+ };
+
+ function localeFirstDayOfWeek () {
+ return this._week.dow;
+ }
+
+ function localeFirstDayOfYear () {
+ return this._week.doy;
+ }
+
+ // MOMENTS
+
+ function getSetWeek (input) {
+ var week = this.localeData().week(this);
+ return input == null ? week : this.add((input - week) * 7, 'd');
+ }
+
+ function getSetISOWeek (input) {
+ var week = weekOfYear(this, 1, 4).week;
+ return input == null ? week : this.add((input - week) * 7, 'd');
+ }
+
+ // FORMATTING
+
addFormatToken('D', ['DD', 2], 'Do', 'date');
// ALIASES
@@ -2205,6 +2585,8 @@
var getSetDayOfMonth = makeGetSet('Date', true);
+ // FORMATTING
+
addFormatToken('d', 0, 'do', 'day');
addFormatToken('dd', 0, 0, function (format) {
@@ -2237,8 +2619,8 @@
addRegexToken('ddd', matchWord);
addRegexToken('dddd', matchWord);
- addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config) {
- var weekday = config._locale.weekdaysParse(input);
+ addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
+ var weekday = config._locale.weekdaysParse(input, token, config._strict);
// if we didn't get a weekday name, mark the date as invalid
if (weekday != null) {
week.d = weekday;
@@ -2273,8 +2655,9 @@
// LOCALES
var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
- function localeWeekdays (m) {
- return this._weekdays[m.day()];
+ function localeWeekdays (m, format) {
+ return isArray(this._weekdays) ? this._weekdays[m.day()] :
+ this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
}
var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
@@ -2287,20 +2670,37 @@
return this._weekdaysMin[m.day()];
}
- function localeWeekdaysParse (weekdayName) {
+ function localeWeekdaysParse (weekdayName, format, strict) {
var i, mom, regex;
- this._weekdaysParse = this._weekdaysParse || [];
+ if (!this._weekdaysParse) {
+ this._weekdaysParse = [];
+ this._minWeekdaysParse = [];
+ this._shortWeekdaysParse = [];
+ this._fullWeekdaysParse = [];
+ }
for (i = 0; i < 7; i++) {
// make the regex if we don't have it already
+
+ mom = local__createLocal([2000, 1]).day(i);
+ if (strict && !this._fullWeekdaysParse[i]) {
+ this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
+ this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
+ this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i');
+ }
if (!this._weekdaysParse[i]) {
- mom = local__createLocal([2000, 1]).day(i);
regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
}
// test the regex
- if (this._weekdaysParse[i].test(weekdayName)) {
+ if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
+ return i;
+ } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
+ return i;
+ } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
+ return i;
+ } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
return i;
}
}
@@ -2309,6 +2709,9 @@
// MOMENTS
function getSetDayOfWeek (input) {
+ if (!this.isValid()) {
+ return input != null ? this : NaN;
+ }
var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
if (input != null) {
input = parseWeekday(input, this.localeData());
@@ -2319,20 +2722,73 @@
}
function getSetLocaleDayOfWeek (input) {
+ if (!this.isValid()) {
+ return input != null ? this : NaN;
+ }
var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
return input == null ? weekday : this.add(input - weekday, 'd');
}
function getSetISODayOfWeek (input) {
+ if (!this.isValid()) {
+ return input != null ? this : NaN;
+ }
// behaves the same as moment#day except
// as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
// as a setter, sunday should belong to the previous week.
return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
}
- addFormatToken('H', ['HH', 2], 0, 'hour');
- addFormatToken('h', ['hh', 2], 0, function () {
+ // FORMATTING
+
+ addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
+
+ // ALIASES
+
+ addUnitAlias('dayOfYear', 'DDD');
+
+ // PARSING
+
+ addRegexToken('DDD', match1to3);
+ addRegexToken('DDDD', match3);
+ addParseToken(['DDD', 'DDDD'], function (input, array, config) {
+ config._dayOfYear = toInt(input);
+ });
+
+ // HELPERS
+
+ // MOMENTS
+
+ function getSetDayOfYear (input) {
+ var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
+ return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
+ }
+
+ // FORMATTING
+
+ function hFormat() {
return this.hours() % 12 || 12;
+ }
+
+ addFormatToken('H', ['HH', 2], 0, 'hour');
+ addFormatToken('h', ['hh', 2], 0, hFormat);
+
+ addFormatToken('hmm', 0, 0, function () {
+ return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
+ });
+
+ addFormatToken('hmmss', 0, 0, function () {
+ return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
+ zeroFill(this.seconds(), 2);
+ });
+
+ addFormatToken('Hmm', 0, 0, function () {
+ return '' + this.hours() + zeroFill(this.minutes(), 2);
+ });
+
+ addFormatToken('Hmmss', 0, 0, function () {
+ return '' + this.hours() + zeroFill(this.minutes(), 2) +
+ zeroFill(this.seconds(), 2);
});
function meridiem (token, lowercase) {
@@ -2361,6 +2817,11 @@
addRegexToken('HH', match1to2, match2);
addRegexToken('hh', match1to2, match2);
+ addRegexToken('hmm', match3to4);
+ addRegexToken('hmmss', match5to6);
+ addRegexToken('Hmm', match3to4);
+ addRegexToken('Hmmss', match5to6);
+
addParseToken(['H', 'HH'], HOUR);
addParseToken(['a', 'A'], function (input, array, config) {
config._isPm = config._locale.isPM(input);
@@ -2370,6 +2831,32 @@
array[HOUR] = toInt(input);
getParsingFlags(config).bigHour = true;
});
+ addParseToken('hmm', function (input, array, config) {
+ var pos = input.length - 2;
+ array[HOUR] = toInt(input.substr(0, pos));
+ array[MINUTE] = toInt(input.substr(pos));
+ getParsingFlags(config).bigHour = true;
+ });
+ addParseToken('hmmss', function (input, array, config) {
+ var pos1 = input.length - 4;
+ var pos2 = input.length - 2;
+ array[HOUR] = toInt(input.substr(0, pos1));
+ array[MINUTE] = toInt(input.substr(pos1, 2));
+ array[SECOND] = toInt(input.substr(pos2));
+ getParsingFlags(config).bigHour = true;
+ });
+ addParseToken('Hmm', function (input, array, config) {
+ var pos = input.length - 2;
+ array[HOUR] = toInt(input.substr(0, pos));
+ array[MINUTE] = toInt(input.substr(pos));
+ });
+ addParseToken('Hmmss', function (input, array, config) {
+ var pos1 = input.length - 4;
+ var pos2 = input.length - 2;
+ array[HOUR] = toInt(input.substr(0, pos1));
+ array[MINUTE] = toInt(input.substr(pos1, 2));
+ array[SECOND] = toInt(input.substr(pos2));
+ });
// LOCALES
@@ -2397,6 +2884,8 @@
// this rule.
var getSetHour = makeGetSet('Hours', true);
+ // FORMATTING
+
addFormatToken('m', ['mm', 2], 0, 'minute');
// ALIASES
@@ -2413,6 +2902,8 @@
var getSetMinute = makeGetSet('Minutes', false);
+ // FORMATTING
+
addFormatToken('s', ['ss', 2], 0, 'second');
// ALIASES
@@ -2429,6 +2920,8 @@
var getSetSecond = makeGetSet('Seconds', false);
+ // FORMATTING
+
addFormatToken('S', 0, 0, function () {
return ~~(this.millisecond() / 100);
});
@@ -2484,6 +2977,8 @@
var getSetMillisecond = makeGetSet('Milliseconds', false);
+ // FORMATTING
+
addFormatToken('z', 0, 0, 'zoneAbbr');
addFormatToken('zz', 0, 0, 'zoneName');
@@ -2499,40 +2994,43 @@
var momentPrototype__proto = Moment.prototype;
- momentPrototype__proto.add = add_subtract__add;
- momentPrototype__proto.calendar = moment_calendar__calendar;
- momentPrototype__proto.clone = clone;
- momentPrototype__proto.diff = diff;
- momentPrototype__proto.endOf = endOf;
- momentPrototype__proto.format = format;
- momentPrototype__proto.from = from;
- momentPrototype__proto.fromNow = fromNow;
- momentPrototype__proto.to = to;
- momentPrototype__proto.toNow = toNow;
- momentPrototype__proto.get = getSet;
- momentPrototype__proto.invalidAt = invalidAt;
- momentPrototype__proto.isAfter = isAfter;
- momentPrototype__proto.isBefore = isBefore;
- momentPrototype__proto.isBetween = isBetween;
- momentPrototype__proto.isSame = isSame;
- momentPrototype__proto.isValid = moment_valid__isValid;
- momentPrototype__proto.lang = lang;
- momentPrototype__proto.locale = locale;
- momentPrototype__proto.localeData = localeData;
- momentPrototype__proto.max = prototypeMax;
- momentPrototype__proto.min = prototypeMin;
- momentPrototype__proto.parsingFlags = parsingFlags;
- momentPrototype__proto.set = getSet;
- momentPrototype__proto.startOf = startOf;
- momentPrototype__proto.subtract = add_subtract__subtract;
- momentPrototype__proto.toArray = toArray;
- momentPrototype__proto.toObject = toObject;
- momentPrototype__proto.toDate = toDate;
- momentPrototype__proto.toISOString = moment_format__toISOString;
- momentPrototype__proto.toJSON = moment_format__toISOString;
- momentPrototype__proto.toString = toString;
- momentPrototype__proto.unix = unix;
- momentPrototype__proto.valueOf = to_type__valueOf;
+ momentPrototype__proto.add = add_subtract__add;
+ momentPrototype__proto.calendar = moment_calendar__calendar;
+ momentPrototype__proto.clone = clone;
+ momentPrototype__proto.diff = diff;
+ momentPrototype__proto.endOf = endOf;
+ momentPrototype__proto.format = format;
+ momentPrototype__proto.from = from;
+ momentPrototype__proto.fromNow = fromNow;
+ momentPrototype__proto.to = to;
+ momentPrototype__proto.toNow = toNow;
+ momentPrototype__proto.get = getSet;
+ momentPrototype__proto.invalidAt = invalidAt;
+ momentPrototype__proto.isAfter = isAfter;
+ momentPrototype__proto.isBefore = isBefore;
+ momentPrototype__proto.isBetween = isBetween;
+ momentPrototype__proto.isSame = isSame;
+ momentPrototype__proto.isSameOrAfter = isSameOrAfter;
+ momentPrototype__proto.isSameOrBefore = isSameOrBefore;
+ momentPrototype__proto.isValid = moment_valid__isValid;
+ momentPrototype__proto.lang = lang;
+ momentPrototype__proto.locale = locale;
+ momentPrototype__proto.localeData = localeData;
+ momentPrototype__proto.max = prototypeMax;
+ momentPrototype__proto.min = prototypeMin;
+ momentPrototype__proto.parsingFlags = parsingFlags;
+ momentPrototype__proto.set = getSet;
+ momentPrototype__proto.startOf = startOf;
+ momentPrototype__proto.subtract = add_subtract__subtract;
+ momentPrototype__proto.toArray = toArray;
+ momentPrototype__proto.toObject = toObject;
+ momentPrototype__proto.toDate = toDate;
+ momentPrototype__proto.toISOString = moment_format__toISOString;
+ momentPrototype__proto.toJSON = toJSON;
+ momentPrototype__proto.toString = toString;
+ momentPrototype__proto.unix = unix;
+ momentPrototype__proto.valueOf = to_type__valueOf;
+ momentPrototype__proto.creationData = creationData;
// Year
momentPrototype__proto.year = getSetYear;
@@ -2618,7 +3116,7 @@
function locale_calendar__calendar (key, mom, now) {
var output = this._calendar[key];
- return typeof output === 'function' ? output.call(mom, now) : output;
+ return isFunction(output) ? output.call(mom, now) : output;
}
var defaultLongDateFormat = {
@@ -2680,29 +3178,14 @@
function relative__relativeTime (number, withoutSuffix, string, isFuture) {
var output = this._relativeTime[string];
- return (typeof output === 'function') ?
+ return (isFunction(output)) ?
output(number, withoutSuffix, string, isFuture) :
output.replace(/%d/i, number);
}
function pastFuture (diff, output) {
var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
- return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
- }
-
- function locale_set__set (config) {
- var prop, i;
- for (i in config) {
- prop = config[i];
- if (typeof prop === 'function') {
- this[i] = prop;
- } else {
- this['_' + i] = prop;
- }
- }
- // 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);
+ return isFunction(format) ? format(output) : format.replace(/%s/i, output);
}
var prototype__proto = Locale.prototype;
@@ -2724,11 +3207,15 @@
prototype__proto.set = locale_set__set;
// Month
- prototype__proto.months = localeMonths;
- prototype__proto._months = defaultLocaleMonths;
- prototype__proto.monthsShort = localeMonthsShort;
- prototype__proto._monthsShort = defaultLocaleMonthsShort;
- prototype__proto.monthsParse = localeMonthsParse;
+ prototype__proto.months = localeMonths;
+ prototype__proto._months = defaultLocaleMonths;
+ prototype__proto.monthsShort = localeMonthsShort;
+ prototype__proto._monthsShort = defaultLocaleMonthsShort;
+ prototype__proto.monthsParse = localeMonthsParse;
+ prototype__proto._monthsRegex = defaultMonthsRegex;
+ prototype__proto.monthsRegex = monthsRegex;
+ prototype__proto._monthsShortRegex = defaultMonthsShortRegex;
+ prototype__proto.monthsShortRegex = monthsShortRegex;
// Week
prototype__proto.week = localeWeek;
@@ -3016,15 +3503,15 @@
var years = round(duration.as('y'));
var a = seconds < thresholds.s && ['s', seconds] ||
- minutes === 1 && ['m'] ||
+ minutes <= 1 && ['m'] ||
minutes < thresholds.m && ['mm', minutes] ||
- hours === 1 && ['h'] ||
+ hours <= 1 && ['h'] ||
hours < thresholds.h && ['hh', hours] ||
- days === 1 && ['d'] ||
+ days <= 1 && ['d'] ||
days < thresholds.d && ['dd', days] ||
- months === 1 && ['M'] ||
+ months <= 1 && ['M'] ||
months < thresholds.M && ['MM', months] ||
- years === 1 && ['y'] || ['yy', years];
+ years <= 1 && ['y'] || ['yy', years];
a[2] = withoutSuffix;
a[3] = +posNegDuration > 0;
@@ -3145,6 +3632,8 @@
// Side effect imports
+ // FORMATTING
+
addFormatToken('X', 0, 0, 'unix');
addFormatToken('x', 0, 0, 'valueOf');
@@ -3162,13 +3651,14 @@
// Side effect imports
- utils_hooks__hooks.version = '2.10.6';
+ utils_hooks__hooks.version = '2.12.0';
setHookCallback(local__createLocal);
utils_hooks__hooks.fn = momentPrototype;
utils_hooks__hooks.min = min;
utils_hooks__hooks.max = max;
+ utils_hooks__hooks.now = now;
utils_hooks__hooks.utc = create_utc__createUTC;
utils_hooks__hooks.unix = moment__createUnix;
utils_hooks__hooks.months = lists__listMonths;
@@ -3184,9 +3674,12 @@
utils_hooks__hooks.monthsShort = lists__listMonthsShort;
utils_hooks__hooks.weekdaysMin = lists__listWeekdaysMin;
utils_hooks__hooks.defineLocale = defineLocale;
+ utils_hooks__hooks.updateLocale = updateLocale;
+ utils_hooks__hooks.locales = locale_locales__listLocales;
utils_hooks__hooks.weekdaysShort = lists__listWeekdaysShort;
utils_hooks__hooks.normalizeUnits = normalizeUnits;
utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;
+ utils_hooks__hooks.prototype = momentPrototype;
var _moment = utils_hooks__hooks;