vendor/assets/javascripts/moment.js in flashgrid-ext-2.2.5 vs vendor/assets/javascripts/moment.js in flashgrid-ext-2.3.0
- old
+ new
@@ -1,43 +1,32 @@
(function (undefined) {
-
/************************************
Constants
************************************/
var moment,
- VERSION = "2.7.0",
+ VERSION = '2.8.2',
// the global-scope this is NOT the global object in Node.js
globalScope = typeof global !== 'undefined' ? global : this,
oldGlobalMoment,
round = Math.round,
+ hasOwnProperty = Object.prototype.hasOwnProperty,
i,
YEAR = 0,
MONTH = 1,
DATE = 2,
HOUR = 3,
MINUTE = 4,
SECOND = 5,
MILLISECOND = 6,
- // internal storage for language config files
- languages = {},
+ // internal storage for locale config files
+ locales = {},
- // moment internal properties
- momentProperties = {
- _isAMomentObject: null,
- _i : null,
- _f : null,
- _l : null,
- _strict : null,
- _tzm : null,
- _isUTC : null,
- _offset : null, // optional. Combine with _isUTC
- _pf : null,
- _lang : null // optional
- },
+ // extra moment internal properties (plugins register props here)
+ momentProperties = [],
// check for nodeJS
hasModule = (typeof module !== 'undefined' && module.exports),
// ASP.NET json date format regex
@@ -92,11 +81,11 @@
['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
['HH:mm', /(T| )\d\d:\d\d/],
['HH', /(T| )\d\d/]
],
- // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"]
+ // timezone chunker '+10:00' > ['10', '00'] or '-1530' > ['-15', '30']
parseTimezoneChunker = /([\+\-]|\d\d)/gi,
// getter and setter names
proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
unitMillisecondFactors = {
@@ -139,16 +128,15 @@
// format function strings
formatFunctions = {},
// default relative time thresholds
relativeTimeThresholds = {
- s: 45, //seconds to minutes
- m: 45, //minutes to hours
- h: 22, //hours to days
- dd: 25, //days to month (month == 1)
- dm: 45, //days to months (months > 1)
- dy: 345 //days to year
+ 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
},
// tokens to ordinalize and pad
ordinalizeTokens = 'DDD w W M D d'.split(' '),
paddedTokens = 'M D H h m s w W'.split(' '),
@@ -156,14 +144,14 @@
formatTokenFunctions = {
M : function () {
return this.month() + 1;
},
MMM : function (format) {
- return this.lang().monthsShort(this, format);
+ return this.localeData().monthsShort(this, format);
},
MMMM : function (format) {
- return this.lang().months(this, format);
+ return this.localeData().months(this, format);
},
D : function () {
return this.date();
},
DDD : function () {
@@ -171,17 +159,17 @@
},
d : function () {
return this.day();
},
dd : function (format) {
- return this.lang().weekdaysMin(this, format);
+ return this.localeData().weekdaysMin(this, format);
},
ddd : function (format) {
- return this.lang().weekdaysShort(this, format);
+ return this.localeData().weekdaysShort(this, format);
},
dddd : function (format) {
- return this.lang().weekdays(this, format);
+ return this.localeData().weekdays(this, format);
},
w : function () {
return this.week();
},
W : function () {
@@ -223,14 +211,14 @@
},
E : function () {
return this.isoWeekday();
},
a : function () {
- return this.lang().meridiem(this.hours(), this.minutes(), true);
+ return this.localeData().meridiem(this.hours(), this.minutes(), true);
},
A : function () {
- return this.lang().meridiem(this.hours(), this.minutes(), false);
+ return this.localeData().meridiem(this.hours(), this.minutes(), false);
},
H : function () {
return this.hours();
},
h : function () {
@@ -254,23 +242,23 @@
SSSS : function () {
return leftZeroFill(this.milliseconds(), 3);
},
Z : function () {
var a = -this.zone(),
- b = "+";
+ b = '+';
if (a < 0) {
a = -a;
- b = "-";
+ b = '-';
}
- return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2);
+ return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2);
},
ZZ : function () {
var a = -this.zone(),
- b = "+";
+ b = '+';
if (a < 0) {
a = -a;
- b = "-";
+ b = '-';
}
return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
},
z : function () {
return this.zoneAbbr();
@@ -284,22 +272,28 @@
Q : function () {
return this.quarter();
}
},
+ deprecations = {},
+
lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'];
// Pick the first defined of two or three arguments. dfl comes from
// default.
function dfl(a, b, c) {
switch (arguments.length) {
case 2: return a != null ? a : b;
case 3: return a != null ? a : b != null ? b : c;
- default: throw new Error("Implement me");
+ default: throw new Error('Implement me');
}
}
+ function hasOwnProp(a, b) {
+ return hasOwnProperty.call(a, b);
+ }
+
function defaultParsingFlags() {
// We need to deep clone this object, and es5 standard is not very
// helpful.
return {
empty : false,
@@ -313,35 +307,43 @@
userInvalidated : false,
iso: false
};
}
+ function printMsg(msg) {
+ if (moment.suppressDeprecationWarnings === false &&
+ typeof console !== 'undefined' && console.warn) {
+ console.warn('Deprecation warning: ' + msg);
+ }
+ }
+
function deprecate(msg, fn) {
var firstTime = true;
- function printMsg() {
- if (moment.suppressDeprecationWarnings === false &&
- typeof console !== 'undefined' && console.warn) {
- console.warn("Deprecation warning: " + msg);
- }
- }
return extend(function () {
if (firstTime) {
- printMsg();
+ printMsg(msg);
firstTime = false;
}
return fn.apply(this, arguments);
}, fn);
}
+ function deprecateSimple(name, msg) {
+ if (!deprecations[name]) {
+ printMsg(msg);
+ deprecations[name] = true;
+ }
+ }
+
function padToken(func, count) {
return function (a) {
return leftZeroFill(func.call(this, a), count);
};
}
function ordinalizeToken(func, period) {
return function (a) {
- return this.lang().ordinal(func.call(this, a), period);
+ return this.localeData().ordinal(func.call(this, a), period);
};
}
while (ordinalizeTokens.length) {
i = ordinalizeTokens.pop();
@@ -356,18 +358,20 @@
/************************************
Constructors
************************************/
- function Language() {
-
+ function Locale() {
}
// Moment prototype object
- function Moment(config) {
- checkOverflow(config);
- extend(this, config);
+ function Moment(config, skipOverflow) {
+ if (skipOverflow !== false) {
+ checkOverflow(config);
+ }
+ copyConfig(this, config);
+ this._d = new Date(+config._d);
}
// Duration Constructor
function Duration(duration) {
var normalizedInput = normalizeObjectUnits(duration),
@@ -397,45 +401,83 @@
quarters * 3 +
years * 12;
this._data = {};
+ this._locale = moment.localeData();
+
this._bubble();
}
/************************************
Helpers
************************************/
function extend(a, b) {
for (var i in b) {
- if (b.hasOwnProperty(i)) {
+ if (hasOwnProp(b, i)) {
a[i] = b[i];
}
}
- if (b.hasOwnProperty("toString")) {
+ if (hasOwnProp(b, 'toString')) {
a.toString = b.toString;
}
- if (b.hasOwnProperty("valueOf")) {
+ if (hasOwnProp(b, 'valueOf')) {
a.valueOf = b.valueOf;
}
return a;
}
- function cloneMoment(m) {
- var result = {}, i;
- for (i in m) {
- if (m.hasOwnProperty(i) && momentProperties.hasOwnProperty(i)) {
- result[i] = m[i];
+ function copyConfig(to, from) {
+ var i, prop, val;
+
+ if (typeof from._isAMomentObject !== 'undefined') {
+ to._isAMomentObject = from._isAMomentObject;
+ }
+ if (typeof from._i !== 'undefined') {
+ to._i = from._i;
+ }
+ if (typeof from._f !== 'undefined') {
+ to._f = from._f;
+ }
+ if (typeof from._l !== 'undefined') {
+ to._l = from._l;
+ }
+ if (typeof from._strict !== 'undefined') {
+ to._strict = from._strict;
+ }
+ if (typeof from._tzm !== 'undefined') {
+ to._tzm = from._tzm;
+ }
+ if (typeof from._isUTC !== 'undefined') {
+ to._isUTC = from._isUTC;
+ }
+ if (typeof from._offset !== 'undefined') {
+ to._offset = from._offset;
+ }
+ if (typeof from._pf !== 'undefined') {
+ to._pf = from._pf;
+ }
+ if (typeof from._locale !== 'undefined') {
+ to._locale = from._locale;
+ }
+
+ if (momentProperties.length > 0) {
+ for (i in momentProperties) {
+ prop = momentProperties[i];
+ val = from[prop];
+ if (typeof val !== 'undefined') {
+ to[prop] = val;
+ }
}
}
- return result;
+ return to;
}
function absRound(number) {
if (number < 0) {
return Math.ceil(number);
@@ -454,11 +496,55 @@
output = '0' + output;
}
return (sign ? (forceSign ? '+' : '') : '-') + output;
}
- // helper function for _.addTime and _.subtractTime
+ function positiveMomentsDifference(base, other) {
+ var res = {milliseconds: 0, months: 0};
+
+ res.months = other.month() - base.month() +
+ (other.year() - base.year()) * 12;
+ if (base.clone().add(res.months, 'M').isAfter(other)) {
+ --res.months;
+ }
+
+ res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
+
+ return res;
+ }
+
+ function momentsDifference(base, other) {
+ var res;
+ other = makeAs(other, base);
+ if (base.isBefore(other)) {
+ res = positiveMomentsDifference(base, other);
+ } else {
+ res = positiveMomentsDifference(other, base);
+ res.milliseconds = -res.milliseconds;
+ res.months = -res.months;
+ }
+
+ return res;
+ }
+
+ // TODO: remove 'name' arg after deprecation is removed
+ function createAdder(direction, name) {
+ return function (val, period) {
+ var dur, tmp;
+ //invert the arguments, but complain about it
+ if (period !== null && !isNaN(+period)) {
+ deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');
+ tmp = val; val = period; period = tmp;
+ }
+
+ val = typeof val === 'string' ? +val : val;
+ dur = moment.duration(val, period);
+ addOrSubtractDurationFromMoment(this, dur, direction);
+ return this;
+ };
+ }
+
function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
var milliseconds = duration._milliseconds,
days = duration._days,
months = duration._months;
updateOffset = updateOffset == null ? true : updateOffset;
@@ -481,12 +567,12 @@
function isArray(input) {
return Object.prototype.toString.call(input) === '[object Array]';
}
function isDate(input) {
- return Object.prototype.toString.call(input) === '[object Date]' ||
- input instanceof Date;
+ return Object.prototype.toString.call(input) === '[object Date]' ||
+ input instanceof Date;
}
// compare two arrays, return the number of differences
function compareArrays(array1, array2, dontConvert) {
var len = Math.min(array1.length, array2.length),
@@ -514,11 +600,11 @@
var normalizedInput = {},
normalizedProp,
prop;
for (prop in inputObject) {
- if (inputObject.hasOwnProperty(prop)) {
+ if (hasOwnProp(inputObject, prop)) {
normalizedProp = normalizeUnits(prop);
if (normalizedProp) {
normalizedInput[normalizedProp] = inputObject[prop];
}
}
@@ -542,21 +628,21 @@
return;
}
moment[field] = function (format, index) {
var i, getter,
- method = moment.fn._lang[field],
+ method = moment._locale[field],
results = [];
if (typeof format === 'number') {
index = format;
format = undefined;
}
getter = function (i) {
var m = moment().utc().set(setter, i);
- return method.call(moment.fn._lang, m, format || '');
+ return method.call(moment._locale, m, format || '');
};
if (index != null) {
return getter(index);
}
@@ -637,26 +723,66 @@
}
}
return m._isValid;
}
- function normalizeLanguage(key) {
+ function normalizeLocale(key) {
return key ? key.toLowerCase().replace('_', '-') : key;
}
+ // pick the locale from the array
+ // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
+ // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
+ function chooseLocale(names) {
+ var i = 0, j, next, locale, split;
+
+ while (i < names.length) {
+ split = normalizeLocale(names[i]).split('-');
+ j = split.length;
+ next = normalizeLocale(names[i + 1]);
+ next = next ? next.split('-') : null;
+ while (j > 0) {
+ locale = loadLocale(split.slice(0, j).join('-'));
+ if (locale) {
+ return locale;
+ }
+ if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
+ //the next array item is better than a shallower substring of this one
+ break;
+ }
+ j--;
+ }
+ i++;
+ }
+ return null;
+ }
+
+ function loadLocale(name) {
+ var oldLocale = null;
+ if (!locales[name] && hasModule) {
+ try {
+ oldLocale = moment.locale();
+ require('./locale/' + name);
+ // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales
+ moment.locale(oldLocale);
+ } catch (e) { }
+ }
+ return locales[name];
+ }
+
// Return a moment from input, that is local/utc/zone equivalent to model.
function makeAs(input, model) {
return model._isUTC ? moment(input).zone(model._offset || 0) :
moment(input).local();
}
/************************************
- Languages
+ Locale
************************************/
- extend(Language.prototype, {
+ extend(Locale.prototype, {
set : function (config) {
var prop, i;
for (i in config) {
prop = config[i];
@@ -666,16 +792,16 @@
this['_' + i] = prop;
}
}
},
- _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
+ _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
months : function (m) {
return this._months[m.month()];
},
- _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
+ _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
monthsShort : function (m) {
return this._monthsShort[m.month()];
},
monthsParse : function (monthName) {
@@ -697,21 +823,21 @@
return i;
}
}
},
- _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
+ _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
weekdays : function (m) {
return this._weekdays[m.day()];
},
- _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
+ _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
weekdaysShort : function (m) {
return this._weekdaysShort[m.day()];
},
- _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
+ _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
weekdaysMin : function (m) {
return this._weekdaysMin[m.day()];
},
weekdaysParse : function (weekdayName) {
@@ -734,15 +860,15 @@
}
}
},
_longDateFormat : {
- LT : "h:mm A",
- L : "MM/DD/YYYY",
- LL : "MMMM D YYYY",
- LLL : "MMMM D YYYY LT",
- LLLL : "dddd, MMMM D YYYY LT"
+ LT : 'h:mm A',
+ L : 'MM/DD/YYYY',
+ LL : 'MMMM D, YYYY',
+ LLL : 'MMMM D, YYYY LT',
+ LLLL : 'dddd, MMMM D, YYYY LT'
},
longDateFormat : function (key) {
var output = this._longDateFormat[key];
if (!output && this._longDateFormat[key.toUpperCase()]) {
output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
@@ -780,39 +906,41 @@
var output = this._calendar[key];
return typeof output === 'function' ? output.apply(mom) : output;
},
_relativeTime : {
- future : "in %s",
- past : "%s ago",
- s : "a few seconds",
- m : "a minute",
- mm : "%d minutes",
- h : "an hour",
- hh : "%d hours",
- d : "a day",
- dd : "%d days",
- M : "a month",
- MM : "%d months",
- y : "a year",
- yy : "%d years"
+ future : 'in %s',
+ past : '%s ago',
+ s : 'a few seconds',
+ m : 'a minute',
+ mm : '%d minutes',
+ h : 'an hour',
+ hh : '%d hours',
+ d : 'a day',
+ dd : '%d days',
+ M : 'a month',
+ MM : '%d months',
+ y : 'a year',
+ yy : '%d years'
},
+
relativeTime : function (number, withoutSuffix, string, isFuture) {
var output = this._relativeTime[string];
return (typeof output === 'function') ?
output(number, withoutSuffix, string, isFuture) :
output.replace(/%d/i, number);
},
+
pastFuture : function (diff, output) {
var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
},
ordinal : function (number) {
- return this._ordinal.replace("%d", number);
+ return this._ordinal.replace('%d', number);
},
- _ordinal : "%d",
+ _ordinal : '%d',
preparse : function (string) {
return string;
},
@@ -833,92 +961,20 @@
invalidDate: function () {
return this._invalidDate;
}
});
- // Loads a language definition into the `languages` cache. The function
- // takes a key and optionally values. If not in the browser and no values
- // are provided, it will load the language file module. As a convenience,
- // this function also returns the language values.
- function loadLang(key, values) {
- values.abbr = key;
- if (!languages[key]) {
- languages[key] = new Language();
- }
- languages[key].set(values);
- return languages[key];
- }
-
- // Remove a language from the `languages` cache. Mostly useful in tests.
- function unloadLang(key) {
- delete languages[key];
- }
-
- // Determines which language definition to use and returns it.
- //
- // With no parameters, it will return the global language. If you
- // pass in a language key, such as 'en', it will return the
- // definition for 'en', so long as 'en' has already been loaded using
- // moment.lang.
- function getLangDefinition(key) {
- var i = 0, j, lang, next, split,
- get = function (k) {
- if (!languages[k] && hasModule) {
- try {
- require('./lang/' + k);
- } catch (e) { }
- }
- return languages[k];
- };
-
- if (!key) {
- return moment.fn._lang;
- }
-
- if (!isArray(key)) {
- //short-circuit everything else
- lang = get(key);
- if (lang) {
- return lang;
- }
- key = [key];
- }
-
- //pick the language from the array
- //try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
- //substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
- while (i < key.length) {
- split = normalizeLanguage(key[i]).split('-');
- j = split.length;
- next = normalizeLanguage(key[i + 1]);
- next = next ? next.split('-') : null;
- while (j > 0) {
- lang = get(split.slice(0, j).join('-'));
- if (lang) {
- return lang;
- }
- if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
- //the next array item is better than a shallower substring of this one
- break;
- }
- j--;
- }
- i++;
- }
- return moment.fn._lang;
- }
-
/************************************
Formatting
************************************/
function removeFormattingTokens(input) {
if (input.match(/\[[\s\S]/)) {
- return input.replace(/^\[|\]$/g, "");
+ return input.replace(/^\[|\]$/g, '');
}
- return input.replace(/\\/g, "");
+ return input.replace(/\\/g, '');
}
function makeFormatFunction(format) {
var array = format.match(formattingTokens), i, length;
@@ -929,39 +985,38 @@
array[i] = removeFormattingTokens(array[i]);
}
}
return function (mom) {
- var output = "";
+ var output = '';
for (i = 0; i < length; i++) {
output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
}
return output;
};
}
// format date using native date object
function formatMoment(m, format) {
-
if (!m.isValid()) {
- return m.lang().invalidDate();
+ return m.localeData().invalidDate();
}
- format = expandFormat(format, m.lang());
+ format = expandFormat(format, m.localeData());
if (!formatFunctions[format]) {
formatFunctions[format] = makeFormatFunction(format);
}
return formatFunctions[format](m);
}
- function expandFormat(format, lang) {
+ function expandFormat(format, locale) {
var i = 5;
function replaceLongDateFormatTokens(input) {
- return lang.longDateFormat(input) || input;
+ return locale.longDateFormat(input) || input;
}
localFormattingTokens.lastIndex = 0;
while (i >= 0 && localFormattingTokens.test(format)) {
format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
@@ -998,17 +1053,23 @@
case 'YYYYY':
case 'GGGGG':
case 'ggggg':
return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
case 'S':
- if (strict) { return parseTokenOneDigit; }
+ if (strict) {
+ return parseTokenOneDigit;
+ }
/* falls through */
case 'SS':
- if (strict) { return parseTokenTwoDigits; }
+ if (strict) {
+ return parseTokenTwoDigits;
+ }
/* falls through */
case 'SSS':
- if (strict) { return parseTokenThreeDigits; }
+ if (strict) {
+ return parseTokenThreeDigits;
+ }
/* falls through */
case 'DDD':
return parseTokenOneToThreeDigits;
case 'MMM':
case 'MMMM':
@@ -1016,11 +1077,11 @@
case 'ddd':
case 'dddd':
return parseTokenWord;
case 'a':
case 'A':
- return getLangDefinition(config._l)._meridiemParse;
+ return config._locale._meridiemParse;
case 'X':
return parseTokenTimestampMs;
case 'Z':
case 'ZZ':
return parseTokenTimezone;
@@ -1053,17 +1114,17 @@
case 'E':
return parseTokenOneOrTwoDigits;
case 'Do':
return parseTokenOrdinal;
default :
- a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i"));
+ a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i'));
return a;
}
}
function timezoneMinutesFromString(string) {
- string = string || "";
+ string = string || '';
var possibleTzMatches = (string.match(parseTokenTimezone) || []),
tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
minutes = +(parts[1] * 60) + toInt(parts[2]);
@@ -1088,11 +1149,11 @@
datePartArray[MONTH] = toInt(input) - 1;
}
break;
case 'MMM' : // fall through to MMMM
case 'MMMM' :
- a = getLangDefinition(config._l).monthsParse(input);
+ a = config._locale.monthsParse(input);
// if we didn't find a month name, mark the date as invalid.
if (a != null) {
datePartArray[MONTH] = a;
} else {
config._pf.invalidMonth = input;
@@ -1128,11 +1189,11 @@
datePartArray[YEAR] = toInt(input);
break;
// AM / PM
case 'a' : // fall through to A
case 'A' :
- config._isPm = getLangDefinition(config._l).isPM(input);
+ config._isPm = config._locale.isPM(input);
break;
// 24 HOUR
case 'H' : // fall through to hh
case 'HH' : // fall through to hh
case 'h' : // fall through to hh
@@ -1168,11 +1229,11 @@
break;
// WEEKDAY - human
case 'dd':
case 'ddd':
case 'dddd':
- a = getLangDefinition(config._l).weekdaysParse(input);
+ a = config._locale.weekdaysParse(input);
// if we didn't get a weekday name, mark the date as invalid
if (a != null) {
config._w = config._w || {};
config._w['d'] = a;
} else {
@@ -1204,11 +1265,11 @@
config._w[token] = moment.parseTwoDigitYear(input);
}
}
function dayOfYearFromWeekInfo(config) {
- var w, weekYear, week, weekday, dow, doy, temp, lang;
+ var w, weekYear, week, weekday, dow, doy, temp;
w = config._w;
if (w.GG != null || w.W != null || w.E != null) {
dow = 1;
doy = 4;
@@ -1219,13 +1280,12 @@
// create now).
weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year);
week = dfl(w.W, 1);
weekday = dfl(w.E, 1);
} else {
- lang = getLangDefinition(config._l);
- dow = lang._week.dow;
- doy = lang._week.doy;
+ dow = config._locale._week.dow;
+ doy = config._locale._week.doy;
weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);
week = dfl(w.w, 1);
if (w.d != null) {
@@ -1335,27 +1395,25 @@
}
}
// date from string and format string
function makeDateFromStringAndFormat(config) {
-
if (config._f === moment.ISO_8601) {
parseISO(config);
return;
}
config._a = [];
config._pf.empty = true;
// This array is used to make a Date, either with `new Date` or `Date.UTC`
- var lang = getLangDefinition(config._l),
- string = '' + config._i,
+ var string = '' + config._i,
i, parsedInput, tokens, token, skipped,
stringLength = string.length,
totalParsedInputLength = 0;
- tokens = expandFormat(config._f, lang).match(formattingTokens) || [];
+ tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
for (i = 0; i < tokens.length; i++) {
token = tokens[i];
parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
if (parsedInput) {
@@ -1426,11 +1484,11 @@
return;
}
for (i = 0; i < config._f.length; i++) {
currentScore = 0;
- tempConfig = extend({}, config);
+ tempConfig = copyConfig({}, config);
tempConfig._pf = defaultParsingFlags();
tempConfig._f = config._f[i];
makeDateFromStringAndFormat(tempConfig);
if (!isValid(tempConfig)) {
@@ -1462,23 +1520,23 @@
if (match) {
config._pf.iso = true;
for (i = 0, l = isoDates.length; i < l; i++) {
if (isoDates[i][1].exec(string)) {
- // match[5] should be "T" or undefined
- config._f = isoDates[i][0] + (match[6] || " ");
+ // match[5] should be 'T' or undefined
+ config._f = isoDates[i][0] + (match[6] || ' ');
break;
}
}
for (i = 0, l = isoTimes.length; i < l; i++) {
if (isoTimes[i][1].exec(string)) {
config._f += isoTimes[i][0];
break;
}
}
if (string.match(parseTokenTimezone)) {
- config._f += "Z";
+ config._f += 'Z';
}
makeDateFromStringAndFormat(config);
} else {
config._isValid = false;
}
@@ -1492,24 +1550,22 @@
moment.createFromInputFallback(config);
}
}
function makeDateFromInput(config) {
- var input = config._i,
- matched = aspNetJsonRegex.exec(input);
-
+ var input = config._i, matched;
if (input === undefined) {
config._d = new Date();
- } else if (matched) {
+ } else if (isDate(input)) {
+ config._d = new Date(+input);
+ } else if ((matched = aspNetJsonRegex.exec(input)) !== null) {
config._d = new Date(+matched[1]);
} else if (typeof input === 'string') {
makeDateFromString(config);
} else if (isArray(input)) {
config._a = input.slice(0);
dateFromConfig(config);
- } else if (isDate(input)) {
- config._d = new Date(+input);
} else if (typeof(input) === 'object') {
dateFromObject(config);
} else if (typeof(input) === 'number') {
// from milliseconds
config._d = new Date(input);
@@ -1536,17 +1592,17 @@
date.setUTCFullYear(y);
}
return date;
}
- function parseWeekday(input, language) {
+ function parseWeekday(input, locale) {
if (typeof input === 'string') {
if (!isNaN(input)) {
input = parseInt(input, 10);
}
else {
- input = language.weekdaysParse(input);
+ input = locale.weekdaysParse(input);
if (typeof input !== 'number') {
return null;
}
}
}
@@ -1557,33 +1613,37 @@
Relative Time
************************************/
// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
- function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) {
- return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
+ function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
+ return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
}
- function relativeTime(milliseconds, withoutSuffix, lang) {
- var seconds = round(Math.abs(milliseconds) / 1000),
- minutes = round(seconds / 60),
- hours = round(minutes / 60),
- days = round(hours / 24),
- years = round(days / 365),
- args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
+ function relativeTime(posNegDuration, withoutSuffix, locale) {
+ var duration = moment.duration(posNegDuration).abs(),
+ seconds = round(duration.as('s')),
+ minutes = round(duration.as('m')),
+ hours = round(duration.as('h')),
+ days = round(duration.as('d')),
+ months = round(duration.as('M')),
+ years = round(duration.as('y')),
+
+ args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
minutes === 1 && ['m'] ||
minutes < relativeTimeThresholds.m && ['mm', minutes] ||
hours === 1 && ['h'] ||
hours < relativeTimeThresholds.h && ['hh', hours] ||
days === 1 && ['d'] ||
- days <= relativeTimeThresholds.dd && ['dd', days] ||
- days <= relativeTimeThresholds.dm && ['M'] ||
- days < relativeTimeThresholds.dy && ['MM', round(days / 30)] ||
+ days < relativeTimeThresholds.d && ['dd', days] ||
+ months === 1 && ['M'] ||
+ months < relativeTimeThresholds.M && ['MM', months] ||
years === 1 && ['y'] || ['yy', years];
+
args[2] = withoutSuffix;
- args[3] = milliseconds > 0;
- args[4] = lang;
+ args[3] = +posNegDuration > 0;
+ args[4] = locale;
return substituteTimeAgo.apply({}, args);
}
/************************************
@@ -1610,11 +1670,11 @@
if (daysToDayOfWeek < end - 7) {
daysToDayOfWeek += 7;
}
- adjustedMoment = moment(mom).add('d', daysToDayOfWeek);
+ adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd');
return {
week: Math.ceil(adjustedMoment.dayOfYear() / 7),
year: adjustedMoment.year()
};
}
@@ -1640,22 +1700,22 @@
function makeMoment(config) {
var input = config._i,
format = config._f;
+ config._locale = config._locale || moment.localeData(config._l);
+
if (input === null || (format === undefined && input === '')) {
return moment.invalid({nullInput: true});
}
if (typeof input === 'string') {
- config._i = input = getLangDefinition().preparse(input);
+ config._i = input = config._locale.preparse(input);
}
if (moment.isMoment(input)) {
- config = cloneMoment(input);
-
- config._d = new Date(+input._d);
+ return new Moment(input, true);
} else if (format) {
if (isArray(format)) {
makeDateFromStringAndArray(config);
} else {
makeDateFromStringAndFormat(config);
@@ -1665,41 +1725,42 @@
}
return new Moment(config);
}
- moment = function (input, format, lang, strict) {
+ moment = function (input, format, locale, strict) {
var c;
- if (typeof(lang) === "boolean") {
- strict = lang;
- lang = undefined;
+ if (typeof(locale) === 'boolean') {
+ strict = locale;
+ locale = undefined;
}
// object construction must be done this way.
// https://github.com/moment/moment/issues/1423
c = {};
c._isAMomentObject = true;
c._i = input;
c._f = format;
- c._l = lang;
+ c._l = locale;
c._strict = strict;
c._isUTC = false;
c._pf = defaultParsingFlags();
return makeMoment(c);
};
moment.suppressDeprecationWarnings = false;
moment.createFromInputFallback = deprecate(
- "moment construction falls back to js Date. This is " +
- "discouraged and will be removed in upcoming major " +
- "release. Please refer to " +
- "https://github.com/moment/moment/issues/1407 for more info.",
- function (config) {
- config._d = new Date(config._i);
- });
+ 'moment construction falls back to js Date. This is ' +
+ 'discouraged and will be removed in upcoming major ' +
+ 'release. Please refer to ' +
+ 'https://github.com/moment/moment/issues/1407 for more info.',
+ function (config) {
+ config._d = new Date(config._i);
+ }
+ );
// Pick a moment m from moments so that m[fn](other) is true for all
// other. This relies on the function fn to be transitive.
//
// moments should either be an array of moment objects or an array, whose
@@ -1732,24 +1793,24 @@
return pickBy('isAfter', args);
};
// creating with utc
- moment.utc = function (input, format, lang, strict) {
+ moment.utc = function (input, format, locale, strict) {
var c;
- if (typeof(lang) === "boolean") {
- strict = lang;
- lang = undefined;
+ if (typeof(locale) === 'boolean') {
+ strict = locale;
+ locale = undefined;
}
// object construction must be done this way.
// https://github.com/moment/moment/issues/1423
c = {};
c._isAMomentObject = true;
c._useUTC = true;
c._isUTC = true;
- c._l = lang;
+ c._l = locale;
c._i = input;
c._f = format;
c._strict = strict;
c._pf = defaultParsingFlags();
@@ -1766,11 +1827,12 @@
var duration = input,
// matching against regexp is expensive, do it on demand
match = null,
sign,
ret,
- parseIso;
+ parseIso,
+ diffRes;
if (moment.isDuration(input)) {
duration = {
ms: input._milliseconds,
d: input._days,
@@ -1782,21 +1844,21 @@
duration[key] = input;
} else {
duration.milliseconds = input;
}
} else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
- sign = (match[1] === "-") ? -1 : 1;
+ sign = (match[1] === '-') ? -1 : 1;
duration = {
y: 0,
d: toInt(match[DATE]) * sign,
h: toInt(match[HOUR]) * sign,
m: toInt(match[MINUTE]) * sign,
s: toInt(match[SECOND]) * sign,
ms: toInt(match[MILLISECOND]) * sign
};
} else if (!!(match = isoDurationRegex.exec(input))) {
- sign = (match[1] === "-") ? -1 : 1;
+ sign = (match[1] === '-') ? -1 : 1;
parseIso = function (inp) {
// We'd normally use ~~inp for this, but unfortunately it also
// converts floats to ints.
// inp may be undefined, so careful calling replace on it.
var res = inp && parseFloat(inp.replace(',', '.'));
@@ -1810,16 +1872,23 @@
h: parseIso(match[5]),
m: parseIso(match[6]),
s: parseIso(match[7]),
w: parseIso(match[8])
};
+ } else if (typeof duration === 'object' &&
+ ('from' in duration || 'to' in duration)) {
+ diffRes = momentsDifference(moment(duration.from), moment(duration.to));
+
+ duration = {};
+ duration.ms = diffRes.milliseconds;
+ duration.M = diffRes.months;
}
ret = new Duration(duration);
- if (moment.isDuration(input) && input.hasOwnProperty('_lang')) {
- ret._lang = input._lang;
+ if (moment.isDuration(input) && hasOwnProp(input, '_locale')) {
+ ret._locale = input._locale;
}
return ret;
};
@@ -1839,50 +1908,103 @@
// This function will be called whenever a moment is mutated.
// It is intended to keep the offset in sync with the timezone.
moment.updateOffset = function () {};
// This function allows you to set a threshold for relative time strings
- moment.relativeTimeThreshold = function(threshold, limit) {
- if (relativeTimeThresholds[threshold] === undefined) {
- return false;
- }
- relativeTimeThresholds[threshold] = limit;
- return true;
+ moment.relativeTimeThreshold = function (threshold, limit) {
+ if (relativeTimeThresholds[threshold] === undefined) {
+ return false;
+ }
+ if (limit === undefined) {
+ return relativeTimeThresholds[threshold];
+ }
+ relativeTimeThresholds[threshold] = limit;
+ return true;
};
- // This function will load languages and then set the global language. If
+ moment.lang = deprecate(
+ 'moment.lang is deprecated. Use moment.locale instead.',
+ function (key, value) {
+ return moment.locale(key, value);
+ }
+ );
+
+ // This function will load locale and then set the global locale. If
// no arguments are passed in, it will simply return the current global
- // language key.
- moment.lang = function (key, values) {
- var r;
- if (!key) {
- return moment.fn._lang._abbr;
+ // locale key.
+ moment.locale = function (key, values) {
+ var data;
+ if (key) {
+ if (typeof(values) !== 'undefined') {
+ data = moment.defineLocale(key, values);
+ }
+ else {
+ data = moment.localeData(key);
+ }
+
+ if (data) {
+ moment.duration._locale = moment._locale = data;
+ }
}
- if (values) {
- loadLang(normalizeLanguage(key), values);
- } else if (values === null) {
- unloadLang(key);
- key = 'en';
- } else if (!languages[key]) {
- getLangDefinition(key);
+
+ return moment._locale._abbr;
+ };
+
+ moment.defineLocale = function (name, values) {
+ if (values !== null) {
+ values.abbr = name;
+ if (!locales[name]) {
+ locales[name] = new Locale();
+ }
+ locales[name].set(values);
+
+ // backwards compat for now: also set the locale
+ moment.locale(name);
+
+ return locales[name];
+ } else {
+ // useful for testing
+ delete locales[name];
+ return null;
}
- r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
- return r._abbr;
};
- // returns language data
- moment.langData = function (key) {
- if (key && key._lang && key._lang._abbr) {
- key = key._lang._abbr;
+ moment.langData = deprecate(
+ 'moment.langData is deprecated. Use moment.localeData instead.',
+ function (key) {
+ return moment.localeData(key);
}
- return getLangDefinition(key);
+ );
+
+ // returns locale data
+ moment.localeData = function (key) {
+ var locale;
+
+ if (key && key._locale && key._locale._abbr) {
+ key = key._locale._abbr;
+ }
+
+ if (!key) {
+ return moment._locale;
+ }
+
+ if (!isArray(key)) {
+ //short-circuit everything else
+ locale = loadLocale(key);
+ if (locale) {
+ return locale;
+ }
+ key = [key];
+ }
+
+ return chooseLocale(key);
};
// compare moment object
moment.isMoment = function (obj) {
return obj instanceof Moment ||
- (obj != null && obj.hasOwnProperty('_isAMomentObject'));
+ (obj != null && hasOwnProp(obj, '_isAMomentObject'));
};
// for typechecking Duration objects
moment.isDuration = function (obj) {
return obj instanceof Duration;
@@ -1934,11 +2056,11 @@
unix : function () {
return Math.floor(+this / 1000);
},
toString : function () {
- return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
+ return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
},
toDate : function () {
return this._offset ? new Date(+this) : this._d;
},
@@ -1968,11 +2090,10 @@
isValid : function () {
return isValid(this);
},
isDSTShifted : function () {
-
if (this._a) {
return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
}
return false;
@@ -1984,52 +2105,34 @@
invalidAt: function () {
return this._pf.overflow;
},
- utc : function () {
- return this.zone(0);
+ utc : function (keepLocalTime) {
+ return this.zone(0, keepLocalTime);
},
- local : function () {
- this.zone(0);
- this._isUTC = false;
+ local : function (keepLocalTime) {
+ if (this._isUTC) {
+ this.zone(0, keepLocalTime);
+ this._isUTC = false;
+
+ if (keepLocalTime) {
+ this.add(this._d.getTimezoneOffset(), 'm');
+ }
+ }
return this;
},
format : function (inputString) {
var output = formatMoment(this, inputString || moment.defaultFormat);
- return this.lang().postformat(output);
+ return this.localeData().postformat(output);
},
- add : function (input, val) {
- var dur;
- // switch args to support add('s', 1) and add(1, 's')
- if (typeof input === 'string' && typeof val === 'string') {
- dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input);
- } else if (typeof input === 'string') {
- dur = moment.duration(+val, input);
- } else {
- dur = moment.duration(input, val);
- }
- addOrSubtractDurationFromMoment(this, dur, 1);
- return this;
- },
+ add : createAdder(1, 'add'),
- subtract : function (input, val) {
- var dur;
- // switch args to support subtract('s', 1) and subtract(1, 's')
- if (typeof input === 'string' && typeof val === 'string') {
- dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input);
- } else if (typeof input === 'string') {
- dur = moment.duration(+val, input);
- } else {
- dur = moment.duration(input, val);
- }
- addOrSubtractDurationFromMoment(this, dur, -1);
- return this;
- },
+ subtract : createAdder(-1, 'subtract'),
diff : function (input, units, asFloat) {
var that = makeAs(input, this),
zoneDiff = (this.zone() - that.zone()) * 6e4,
diff, output;
@@ -2062,11 +2165,11 @@
}
return asFloat ? output : absRound(output);
},
from : function (time, withoutSuffix) {
- return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix);
+ return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
},
fromNow : function (withoutSuffix) {
return this.from(moment(), withoutSuffix);
},
@@ -2081,11 +2184,11 @@
diff < -1 ? 'lastWeek' :
diff < 0 ? 'lastDay' :
diff < 1 ? 'sameDay' :
diff < 2 ? 'nextDay' :
diff < 7 ? 'nextWeek' : 'sameElse';
- return this.format(this.lang().calendar(format, this));
+ return this.format(this.localeData().calendar(format, this));
},
isLeapYear : function () {
return isLeapYear(this.year());
},
@@ -2096,20 +2199,20 @@
},
day : function (input) {
var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
if (input != null) {
- input = parseWeekday(input, this.lang());
- return this.add({ d : input - day });
+ input = parseWeekday(input, this.localeData());
+ return this.add(input - day, 'd');
} else {
return day;
}
},
month : makeAccessor('Month', true),
- startOf: function (units) {
+ startOf : function (units) {
units = normalizeUnits(units);
// the following switch intentionally omits break keywords
// to utilize falling through the cases.
switch (units) {
case 'year':
@@ -2150,11 +2253,11 @@
return this;
},
endOf: function (units) {
units = normalizeUnits(units);
- return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1);
+ return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
},
isAfter: function (input, units) {
units = typeof units !== 'undefined' ? units : 'millisecond';
return +this.clone().startOf(units) > +moment(input).startOf(units);
@@ -2169,48 +2272,55 @@
units = units || 'ms';
return +this.clone().startOf(units) === +makeAs(input, this).startOf(units);
},
min: deprecate(
- "moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",
+ 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
function (other) {
other = moment.apply(null, arguments);
return other < this ? this : other;
}
),
max: deprecate(
- "moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",
+ 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
function (other) {
other = moment.apply(null, arguments);
return other > this ? this : other;
}
),
- // keepTime = true means only change the timezone, without affecting
- // the local hour. So 5:31:26 +0300 --[zone(2, true)]--> 5:31:26 +0200
- // It is possible that 5:31:26 doesn't exist int zone +0200, so we
- // adjust the time as needed, to be valid.
+ // keepLocalTime = true means only change the timezone, without
+ // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]-->
+ // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone
+ // +0200, so we adjust the time as needed, to be valid.
//
// Keeping the time actually adds/subtracts (one hour)
// from the actual represented time. That is why we call updateOffset
// 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.
- zone : function (input, keepTime) {
- var offset = this._offset || 0;
+ zone : function (input, keepLocalTime) {
+ var offset = this._offset || 0,
+ localAdjust;
if (input != null) {
- if (typeof input === "string") {
+ if (typeof input === 'string') {
input = timezoneMinutesFromString(input);
}
if (Math.abs(input) < 16) {
input = input * 60;
}
+ if (!this._isUTC && keepLocalTime) {
+ localAdjust = this._d.getTimezoneOffset();
+ }
this._offset = input;
this._isUTC = true;
+ if (localAdjust != null) {
+ this.subtract(localAdjust, 'm');
+ }
if (offset !== input) {
- if (!keepTime || this._changeInProgress) {
+ if (!keepLocalTime || this._changeInProgress) {
addOrSubtractDurationFromMoment(this,
moment.duration(offset - input, 'm'), 1, false);
} else if (!this._changeInProgress) {
this._changeInProgress = true;
moment.updateOffset(this, true);
@@ -2222,15 +2332,15 @@
}
return this;
},
zoneAbbr : function () {
- return this._isUTC ? "UTC" : "";
+ return this._isUTC ? 'UTC' : '';
},
zoneName : function () {
- return this._isUTC ? "Coordinated Universal Time" : "";
+ return this._isUTC ? 'Coordinated Universal Time' : '';
},
parseZone : function () {
if (this._tzm) {
this.zone(this._tzm);
@@ -2255,40 +2365,40 @@
return daysInMonth(this.year(), this.month());
},
dayOfYear : function (input) {
var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
- return input == null ? dayOfYear : this.add("d", (input - dayOfYear));
+ return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
},
quarter : function (input) {
return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
},
weekYear : function (input) {
- var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year;
- return input == null ? year : this.add("y", (input - year));
+ var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
+ return input == null ? year : this.add((input - year), 'y');
},
isoWeekYear : function (input) {
var year = weekOfYear(this, 1, 4).year;
- return input == null ? year : this.add("y", (input - year));
+ return input == null ? year : this.add((input - year), 'y');
},
week : function (input) {
- var week = this.lang().week(this);
- return input == null ? week : this.add("d", (input - week) * 7);
+ var week = this.localeData().week(this);
+ return input == null ? week : this.add((input - week) * 7, 'd');
},
isoWeek : function (input) {
var week = weekOfYear(this, 1, 4).week;
- return input == null ? week : this.add("d", (input - week) * 7);
+ return input == null ? week : this.add((input - week) * 7, 'd');
},
weekday : function (input) {
- var weekday = (this.day() + 7 - this.lang()._week.dow) % 7;
- return input == null ? weekday : this.add("d", input - weekday);
+ var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
+ return input == null ? weekday : this.add(input - weekday, 'd');
},
isoWeekday : function (input) {
// behaves the same as moment#day except
// as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
@@ -2299,11 +2409,11 @@
isoWeeksInYear : function () {
return weeksInYear(this.year(), 1, 4);
},
weeksInYear : function () {
- var weekInfo = this._lang._week;
+ var weekInfo = this.localeData()._week;
return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
},
get : function (units) {
units = normalizeUnits(units);
@@ -2316,29 +2426,45 @@
this[units](value);
}
return this;
},
- // If passed a language key, it will set the language for this
- // instance. Otherwise, it will return the language configuration
+ // If passed a locale key, it will set the locale for this
+ // instance. Otherwise, it will return the locale configuration
// variables for this instance.
- lang : function (key) {
+ locale : function (key) {
if (key === undefined) {
- return this._lang;
+ return this._locale._abbr;
} else {
- this._lang = getLangDefinition(key);
+ this._locale = moment.localeData(key);
return this;
}
+ },
+
+ lang : deprecate(
+ 'moment().lang() is deprecated. Use moment().localeData() instead.',
+ function (key) {
+ if (key === undefined) {
+ return this.localeData();
+ } else {
+ this._locale = moment.localeData(key);
+ return this;
+ }
+ }
+ ),
+
+ localeData : function () {
+ return this._locale;
}
});
function rawMonthSetter(mom, value) {
var dayOfMonth;
// TODO: Move this out of here!
if (typeof value === 'string') {
- value = mom.lang().monthsParse(value);
+ value = mom.localeData().monthsParse(value);
// TODO: Another silent failure?
if (typeof value !== 'number') {
return mom;
}
}
@@ -2381,13 +2507,13 @@
// a new timezone) makes sense. Adding/subtracting hours does not follow
// this rule.
moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);
// moment.fn.month is defined separately
moment.fn.date = makeAccessor('Date', true);
- moment.fn.dates = deprecate("dates accessor is deprecated. Use date instead.", makeAccessor('Date', true));
+ moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true));
moment.fn.year = makeAccessor('FullYear', true);
- moment.fn.years = deprecate("years accessor is deprecated. Use year instead.", makeAccessor('FullYear', true));
+ moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true));
// add plural methods
moment.fn.days = moment.fn.day;
moment.fn.months = moment.fn.month;
moment.fn.weeks = moment.fn.week;
@@ -2400,18 +2526,29 @@
/************************************
Duration Prototype
************************************/
+ function daysToYears (days) {
+ // 400 years have 146097 days (taking into account leap year rules)
+ return days * 400 / 146097;
+ }
+
+ function yearsToDays (years) {
+ // years * 365 + absRound(years / 4) -
+ // absRound(years / 100) + absRound(years / 400);
+ return years * 146097 / 400;
+ }
+
extend(moment.duration.fn = Duration.prototype, {
_bubble : function () {
var milliseconds = this._milliseconds,
days = this._days,
months = this._months,
data = this._data,
- seconds, minutes, hours, years;
+ seconds, minutes, hours, years = 0;
// The following code bubbles up values, see the tests for
// examples of what that means.
data.milliseconds = milliseconds % 1000;
@@ -2423,19 +2560,44 @@
hours = absRound(minutes / 60);
data.hours = hours % 24;
days += absRound(hours / 24);
- data.days = days % 30;
+ // Accurately convert days to years, assume start from year 0.
+ years = absRound(daysToYears(days));
+ days -= absRound(yearsToDays(years));
+
+ // 30 days to a month
+ // TODO (iskren): Use anchor date (like 1st Jan) to compute this.
months += absRound(days / 30);
- data.months = months % 12;
+ days %= 30;
- years = absRound(months / 12);
+ // 12 months -> 1 year
+ years += absRound(months / 12);
+ months %= 12;
+
+ data.days = days;
+ data.months = months;
data.years = years;
},
+ abs : function () {
+ this._milliseconds = Math.abs(this._milliseconds);
+ this._days = Math.abs(this._days);
+ this._months = Math.abs(this._months);
+
+ this._data.milliseconds = Math.abs(this._data.milliseconds);
+ this._data.seconds = Math.abs(this._data.seconds);
+ this._data.minutes = Math.abs(this._data.minutes);
+ this._data.hours = Math.abs(this._data.hours);
+ this._data.months = Math.abs(this._data.months);
+ this._data.years = Math.abs(this._data.years);
+
+ return this;
+ },
+
weeks : function () {
return absRound(this.days() / 7);
},
valueOf : function () {
@@ -2444,18 +2606,17 @@
(this._months % 12) * 2592e6 +
toInt(this._months / 12) * 31536e6;
},
humanize : function (withSuffix) {
- var difference = +this,
- output = relativeTime(difference, !withSuffix, this.lang());
+ var output = relativeTime(this, !withSuffix, this.localeData());
if (withSuffix) {
- output = this.lang().pastFuture(difference, output);
+ output = this.localeData().pastFuture(+this, output);
}
- return this.lang().postformat(output);
+ return this.localeData().postformat(output);
},
add : function (input, val) {
// supports only 2.0-style add(1, 's') or add(moment)
var dur = moment.duration(input, val);
@@ -2485,17 +2646,43 @@
units = normalizeUnits(units);
return this[units.toLowerCase() + 's']();
},
as : function (units) {
+ var days, months;
units = normalizeUnits(units);
- return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's']();
+
+ days = this._days + this._milliseconds / 864e5;
+ if (units === 'month' || units === 'year') {
+ months = this._months + daysToYears(days) * 12;
+ return units === 'month' ? months : months / 12;
+ } else {
+ days += yearsToDays(this._months / 12);
+ switch (units) {
+ case 'week': return days / 7;
+ case 'day': return days;
+ case 'hour': return days * 24;
+ case 'minute': return days * 24 * 60;
+ case 'second': return days * 24 * 60 * 60;
+ case 'millisecond': return days * 24 * 60 * 60 * 1000;
+ default: throw new Error('Unknown unit ' + units);
+ }
+ }
},
lang : moment.fn.lang,
+ locale : moment.fn.locale,
- toIsoString : function () {
+ toIsoString : deprecate(
+ 'toIsoString() is deprecated. Please use toISOString() instead ' +
+ '(notice the capitals)',
+ function () {
+ return this.toISOString();
+ }
+ ),
+
+ toISOString : function () {
// inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
var years = Math.abs(this.years()),
months = Math.abs(this.months()),
days = Math.abs(this.days()),
hours = Math.abs(this.hours()),
@@ -2515,56 +2702,74 @@
(days ? days + 'D' : '') +
((hours || minutes || seconds) ? 'T' : '') +
(hours ? hours + 'H' : '') +
(minutes ? minutes + 'M' : '') +
(seconds ? seconds + 'S' : '');
+ },
+
+ localeData : function () {
+ return this._locale;
}
});
+ moment.duration.fn.toString = moment.duration.fn.toISOString;
+
function makeDurationGetter(name) {
moment.duration.fn[name] = function () {
return this._data[name];
};
}
- function makeDurationAsGetter(name, factor) {
- moment.duration.fn['as' + name] = function () {
- return +this / factor;
- };
- }
-
for (i in unitMillisecondFactors) {
- if (unitMillisecondFactors.hasOwnProperty(i)) {
- makeDurationAsGetter(i, unitMillisecondFactors[i]);
+ if (hasOwnProp(unitMillisecondFactors, i)) {
makeDurationGetter(i.toLowerCase());
}
}
- makeDurationAsGetter('Weeks', 6048e5);
+ moment.duration.fn.asMilliseconds = function () {
+ return this.as('ms');
+ };
+ moment.duration.fn.asSeconds = function () {
+ return this.as('s');
+ };
+ moment.duration.fn.asMinutes = function () {
+ return this.as('m');
+ };
+ moment.duration.fn.asHours = function () {
+ return this.as('h');
+ };
+ moment.duration.fn.asDays = function () {
+ return this.as('d');
+ };
+ moment.duration.fn.asWeeks = function () {
+ return this.as('weeks');
+ };
moment.duration.fn.asMonths = function () {
- return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12;
+ return this.as('M');
};
+ moment.duration.fn.asYears = function () {
+ return this.as('y');
+ };
-
/************************************
- Default Lang
+ Default Locale
************************************/
- // Set default language, other languages will inherit from English.
- moment.lang('en', {
+ // Set default locale, other locale will inherit from English.
+ moment.locale('en', {
ordinal : function (number) {
var b = number % 10,
output = (toInt(number % 100 / 10) === 1) ? 'th' :
(b === 1) ? 'st' :
(b === 2) ? 'nd' :
(b === 3) ? 'rd' : 'th';
return number + output;
}
});
- /* EMBED_LANGUAGES */
+ /* EMBED_LOCALES */
/************************************
Exposing Moment
************************************/
@@ -2574,23 +2779,23 @@
return;
}
oldGlobalMoment = globalScope.moment;
if (shouldDeprecate) {
globalScope.moment = deprecate(
- "Accessing Moment through the global scope is " +
- "deprecated, and will be removed in an upcoming " +
- "release.",
+ 'Accessing Moment through the global scope is ' +
+ 'deprecated, and will be removed in an upcoming ' +
+ 'release.',
moment);
} else {
globalScope.moment = moment;
}
}
// CommonJS module is defined
if (hasModule) {
module.exports = moment;
- } else if (typeof define === "function" && define.amd) {
- define("moment", function (require, exports, module) {
+ } else if (typeof define === 'function' && define.amd) {
+ define('moment', function (require, exports, module) {
if (module.config && module.config() && module.config().noGlobal === true) {
// release the global variable
globalScope.moment = oldGlobalMoment;
}
\ No newline at end of file