Commit 299053f2 by Torkel Ödegaard

Fix for utc in timepicker, Closes #713

parent a64604de
......@@ -193,8 +193,8 @@ function (angular, app, _, moment, kbn) {
moment(model.to.date).fromNow();
}
else {
model.rangeString = $scope.dashboard.formatDate(model.from.date, 'MMM D, YYYY hh:mm:ss') + ' to ' +
$scope.dashboard.formatDate(model.to.date, 'MMM D, YYYY hh:mm:ss');
model.rangeString = $scope.dashboard.formatDate(model.from.date, 'MMM D, YYYY HH:mm:ss') + ' to ' +
$scope.dashboard.formatDate(model.to.date, 'MMM D, YYYY HH:mm:ss');
}
}
......
//! moment.js
//! version : 2.5.1
//! version : 2.8.1
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com
(function (undefined) {
/************************************
Constants
************************************/
var moment,
VERSION = "2.5.1",
global = this,
VERSION = '2.8.1',
// the global-scope this is NOT the global object in Node.js
globalScope = typeof global !== 'undefined' ? global : this,
oldGlobalMoment,
round = Math.round,
i,
......@@ -24,24 +25,14 @@
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,
_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 && typeof require !== 'undefined'),
hasModule = (typeof module !== 'undefined' && module.exports),
// ASP.NET json date format regex
aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
......@@ -52,7 +43,7 @@
isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,
// format tokens
formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g,
formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g,
localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
// parsing token regexes
......@@ -65,6 +56,7 @@
parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
parseTokenT = /T/i, // T (ISO separator)
parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
parseTokenOrdinal = /\d{1,2}/,
//strict parsing regexes
parseTokenOneDigit = /\d/, // 0 - 9
......@@ -90,7 +82,7 @@
// iso time formats and regexes
isoTimes = [
['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/],
['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/]
......@@ -121,6 +113,7 @@
w : 'week',
W : 'isoWeek',
M : 'month',
Q : 'quarter',
y : 'year',
DDD : 'dayOfYear',
e : 'weekday',
......@@ -140,6 +133,15 @@
// format function strings
formatFunctions = {},
// default relative time thresholds
relativeTimeThresholds = {
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(' '),
......@@ -149,10 +151,10 @@
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();
......@@ -164,13 +166,13 @@
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();
......@@ -216,10 +218,10 @@
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();
......@@ -247,19 +249,19 @@
},
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);
},
......@@ -277,8 +279,20 @@
}
},
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');
}
}
function defaultParsingFlags() {
// We need to deep clone this object, and es5 standard is not very
// helpful.
......@@ -296,6 +310,31 @@
};
}
function printMsg(msg) {
if (moment.suppressDeprecationWarnings === false &&
typeof console !== 'undefined' && console.warn) {
console.warn("Deprecation warning: " + msg);
}
}
function deprecate(msg, fn) {
var firstTime = true;
return extend(function () {
if (firstTime) {
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);
......@@ -303,7 +342,7 @@
}
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);
};
}
......@@ -322,20 +361,23 @@
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),
years = normalizedInput.year || 0,
quarters = normalizedInput.quarter || 0,
months = normalizedInput.month || 0,
weeks = normalizedInput.week || 0,
days = normalizedInput.day || 0,
......@@ -357,10 +399,13 @@
// which months you are are talking about, so we have to store
// it separately.
this._months = +months +
quarters * 3 +
years * 12;
this._data = {};
this._locale = moment.localeData();
this._bubble();
}
......@@ -376,26 +421,62 @@
}
}
if (b.hasOwnProperty("toString")) {
if (b.hasOwnProperty('toString')) {
a.toString = b.toString;
}
if (b.hasOwnProperty("valueOf")) {
if (b.hasOwnProperty('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) {
......@@ -418,35 +499,68 @@
return (sign ? (forceSign ? '+' : '') : '-') + output;
}
// helper function for _.addTime and _.subtractTime
function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) {
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,
minutes,
hours;
months = duration._months;
updateOffset = updateOffset == null ? true : updateOffset;
if (milliseconds) {
mom._d.setTime(+mom._d + milliseconds * isAdding);
}
// store the minutes and hours so we can restore them
if (days || months) {
minutes = mom.minute();
hours = mom.hour();
}
if (days) {
mom.date(mom.date() + days * isAdding);
rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding);
}
if (months) {
mom.month(mom.month() + months * isAdding);
}
if (milliseconds && !ignoreUpdateOffset) {
moment.updateOffset(mom);
rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding);
}
// restore the minutes and hours after possibly changing dst
if (days || months) {
mom.minute(minutes);
mom.hour(hours);
if (updateOffset) {
moment.updateOffset(mom, days || months);
}
}
......@@ -456,8 +570,8 @@
}
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
......@@ -517,7 +631,7 @@
moment[field] = function (format, index) {
var i, getter,
method = moment.fn._lang[field],
method = moment._locale[field],
results = [];
if (typeof format === 'number') {
......@@ -527,7 +641,7 @@
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) {
......@@ -561,6 +675,10 @@
return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
}
function weeksInYear(year, dow, doy) {
return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week;
}
function daysInYear(year) {
return isLeapYear(year) ? 366 : 365;
}
......@@ -608,10 +726,50 @@
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) :
......@@ -619,11 +777,11 @@
}
/************************************
Languages
Locale
************************************/
extend(Language.prototype, {
extend(Locale.prototype, {
set : function (config) {
var prop, i;
......@@ -637,12 +795,12 @@
}
},
_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()];
},
......@@ -668,17 +826,17 @@
}
},
_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()];
},
......@@ -705,11 +863,11 @@
},
_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];
......@@ -751,35 +909,37 @@
},
_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;
......@@ -804,78 +964,6 @@
}
});
// 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
************************************/
......@@ -883,9 +971,9 @@
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) {
......@@ -900,7 +988,7 @@
}
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];
}
......@@ -910,12 +998,11 @@
// 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);
......@@ -924,11 +1011,11 @@
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;
......@@ -951,6 +1038,8 @@
function getParseRegexForToken(token, config) {
var a, strict = config._strict;
switch (token) {
case 'Q':
return parseTokenOneDigit;
case 'DDDD':
return parseTokenThreeDigits;
case 'YYYY':
......@@ -967,13 +1056,19 @@
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;
......@@ -985,7 +1080,7 @@
return parseTokenWord;
case 'a':
case 'A':
return getLangDefinition(config._l)._meridiemParse;
return config._locale._meridiemParse;
case 'X':
return parseTokenTimestampMs;
case 'Z':
......@@ -1019,14 +1114,16 @@
case 'e':
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],
......@@ -1040,6 +1137,12 @@
var a, datePartArray = config._a;
switch (token) {
// QUARTER
case 'Q':
if (input != null) {
datePartArray[MONTH] = (toInt(input) - 1) * 3;
}
break;
// MONTH
case 'M' : // fall through to MM
case 'MM' :
......@@ -1049,7 +1152,7 @@
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;
......@@ -1064,6 +1167,11 @@
datePartArray[DATE] = toInt(input);
}
break;
case 'Do' :
if (input != null) {
datePartArray[DATE] = toInt(parseInt(input, 10));
}
break;
// DAY OF YEAR
case 'DDD' : // fall through to DDDD
case 'DDDD' :
......@@ -1074,7 +1182,7 @@
break;
// YEAR
case 'YY' :
datePartArray[YEAR] = toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
datePartArray[YEAR] = moment.parseTwoDigitYear(input);
break;
case 'YYYY' :
case 'YYYYY' :
......@@ -1084,7 +1192,7 @@
// 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
......@@ -1120,30 +1228,85 @@
config._useUTC = true;
config._tzm = timezoneMinutesFromString(input);
break;
// WEEKDAY - human
case 'dd':
case 'ddd':
case 'dddd':
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 {
config._pf.invalidWeekday = input;
}
break;
// WEEK, WEEK DAY - numeric
case 'w':
case 'ww':
case 'W':
case 'WW':
case 'd':
case 'dd':
case 'ddd':
case 'dddd':
case 'e':
case 'E':
token = token.substr(0, 1);
/* falls through */
case 'gg':
case 'gggg':
case 'GG':
case 'GGGG':
case 'GGGGG':
token = token.substr(0, 2);
if (input) {
config._w = config._w || {};
config._w[token] = input;
config._w[token] = toInt(input);
}
break;
case 'gg':
case 'GG':
config._w = config._w || {};
config._w[token] = moment.parseTwoDigitYear(input);
}
}
function dayOfYearFromWeekInfo(config) {
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;
// TODO: We need to take the current isoWeekYear, but that depends on
// how we interpret now (local, utc, fixed offset). So create
// a now version of current config (take local/utc/offset flags, and
// 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 {
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) {
// weekday -- low day numbers are considered next week
weekday = w.d;
if (weekday < dow) {
++week;
}
} else if (w.e != null) {
// local weekday -- counting starts from begining of week
weekday = w.e + dow;
} else {
// default to begining of week
weekday = dow;
}
}
temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);
config._a[YEAR] = temp.year;
config._dayOfYear = temp.dayOfYear;
}
// convert an array to a date.
......@@ -1151,8 +1314,7 @@
// note: all values past the year are optional and will default to the lowest possible value.
// [year, month, day , hour, minute, second, millisecond]
function dateFromConfig(config) {
var i, date, input = [], currentDate,
yearToUse, fixYear, w, temp, lang, weekday, week;
var i, date, input = [], currentDate, yearToUse;
if (config._d) {
return;
......@@ -1162,39 +1324,12 @@
//compute day of the year from weeks and weekdays
if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
fixYear = function (val) {
var int_val = parseInt(val, 10);
return val ?
(val.length < 3 ? (int_val > 68 ? 1900 + int_val : 2000 + int_val) : int_val) :
(config._a[YEAR] == null ? moment().weekYear() : config._a[YEAR]);
};
w = config._w;
if (w.GG != null || w.W != null || w.E != null) {
temp = dayOfYearFromWeeks(fixYear(w.GG), w.W || 1, w.E, 4, 1);
}
else {
lang = getLangDefinition(config._l);
weekday = w.d != null ? parseWeekday(w.d, lang) :
(w.e != null ? parseInt(w.e, 10) + lang._week.dow : 0);
week = parseInt(w.w, 10) || 1;
//if we're parsing 'd', then the low day numbers may be next week
if (w.d != null && weekday < lang._week.dow) {
week++;
}
temp = dayOfYearFromWeeks(fixYear(w.gg), week, weekday, lang._week.doy, lang._week.dow);
}
config._a[YEAR] = temp.year;
config._dayOfYear = temp.dayOfYear;
dayOfYearFromWeekInfo(config);
}
//if the day of the year is set, figure out what it is
if (config._dayOfYear) {
yearToUse = config._a[YEAR] == null ? currentDate[YEAR] : config._a[YEAR];
yearToUse = dfl(config._a[YEAR], currentDate[YEAR]);
if (config._dayOfYear > daysInYear(yearToUse)) {
config._pf._overflowDayOfYear = true;
......@@ -1219,11 +1354,12 @@
config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
}
// add the offsets to the time to be parsed so that we can have a clean array for checking isValid
input[HOUR] += toInt((config._tzm || 0) / 60);
input[MINUTE] += toInt((config._tzm || 0) % 60);
config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input);
// Apply timezone offset from input. The actual zone can be changed
// with parseZone.
if (config._tzm != null) {
config._d.setUTCMinutes(config._d.getUTCMinutes() + config._tzm);
}
}
function dateFromObject(config) {
......@@ -1262,18 +1398,21 @@
// 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];
......@@ -1348,7 +1487,7 @@
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);
......@@ -1375,7 +1514,7 @@
}
// date from iso format
function makeDateFromString(config) {
function parseISO(config) {
var i, l,
string = config._i,
match = isoRegex.exec(string);
......@@ -1385,7 +1524,7 @@
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] || " ");
config._f = isoDates[i][0] + (match[6] || ' ');
break;
}
}
......@@ -1396,34 +1535,43 @@
}
}
if (string.match(parseTokenTimezone)) {
config._f += "Z";
config._f += 'Z';
}
makeDateFromStringAndFormat(config);
} else {
config._isValid = false;
}
else {
config._d = new Date(string);
}
// date from iso format or fallback
function makeDateFromString(config) {
parseISO(config);
if (config._isValid === false) {
delete config._isValid;
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 {
} else if (typeof(input) === 'number') {
// from milliseconds
config._d = new Date(input);
} else {
moment.createFromInputFallback(config);
}
}
......@@ -1447,13 +1595,13 @@
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;
}
......@@ -1468,29 +1616,33 @@
// 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 < 45 && ['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 < 45 && ['mm', minutes] ||
minutes < relativeTimeThresholds.m && ['mm', minutes] ||
hours === 1 && ['h'] ||
hours < 22 && ['hh', hours] ||
hours < relativeTimeThresholds.h && ['hh', hours] ||
days === 1 && ['d'] ||
days <= 25 && ['dd', days] ||
days <= 45 && ['M'] ||
days < 345 && ['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);
}
......@@ -1521,7 +1673,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()
......@@ -1532,6 +1684,7 @@
function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear;
d = d === 0 ? 7 : d;
weekday = weekday != null ? weekday : firstDayOfWeek;
daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);
dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;
......@@ -1550,18 +1703,18 @@
var input = config._i,
format = config._f;
if (input === null) {
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);
......@@ -1575,12 +1728,12 @@
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
......@@ -1588,7 +1741,7 @@
c._isAMomentObject = true;
c._i = input;
c._f = format;
c._l = lang;
c._l = locale;
c._strict = strict;
c._isUTC = false;
c._pf = defaultParsingFlags();
......@@ -1596,13 +1749,59 @@
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);
}
);
// 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
// first element is an array of moment objects.
function pickBy(fn, moments) {
var res, i;
if (moments.length === 1 && isArray(moments[0])) {
moments = moments[0];
}
if (!moments.length) {
return moment();
}
res = moments[0];
for (i = 1; i < moments.length; ++i) {
if (moments[i][fn](res)) {
res = moments[i];
}
}
return res;
}
moment.min = function () {
var args = [].slice.call(arguments, 0);
return pickBy('isBefore', args);
};
moment.max = function () {
var args = [].slice.call(arguments, 0);
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
......@@ -1610,7 +1809,7 @@
c._isAMomentObject = true;
c._useUTC = true;
c._isUTC = true;
c._l = lang;
c._l = locale;
c._i = input;
c._f = format;
c._strict = strict;
......@@ -1631,7 +1830,8 @@
match = null,
sign,
ret,
parseIso;
parseIso,
diffRes;
if (moment.isDuration(input)) {
duration = {
......@@ -1647,7 +1847,7 @@
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,
......@@ -1657,7 +1857,7 @@
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.
......@@ -1675,12 +1875,19 @@
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) && input.hasOwnProperty('_locale')) {
ret._locale = input._locale;
}
return ret;
......@@ -1692,36 +1899,105 @@
// default format
moment.defaultFormat = isoFormat;
// constant that refers to the ISO standard
moment.ISO_8601 = function () {};
// Plugins that add properties should also add the key here (null value),
// so we can properly clone ourselves.
moment.momentProperties = momentProperties;
// 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 will load languages and then set the global language. If
// This function allows you to set a threshold for relative time strings
moment.relativeTimeThreshold = function (threshold, limit) {
if (relativeTimeThresholds[threshold] === undefined) {
return false;
}
if (limit === undefined) {
return relativeTimeThresholds[threshold];
}
relativeTimeThresholds[threshold] = limit;
return true;
};
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;
}
if (values) {
loadLang(normalizeLanguage(key), values);
} else if (values === null) {
unloadLang(key);
key = 'en';
} else if (!languages[key]) {
getLangDefinition(key);
}
r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
return r._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;
}
}
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;
}
};
// 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);
}
);
// 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 getLangDefinition(key);
return chooseLocale(key);
};
// compare moment object
......@@ -1755,8 +2031,12 @@
return m;
};
moment.parseZone = function (input) {
return moment(input).parseZone();
moment.parseZone = function () {
return moment.apply(null, arguments).parseZone();
};
moment.parseTwoDigitYear = function (input) {
return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
};
/************************************
......@@ -1779,7 +2059,7 @@
},
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 () {
......@@ -1813,7 +2093,6 @@
},
isDSTShifted : function () {
if (this._a) {
return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
}
......@@ -1829,44 +2108,30 @@
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') {
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') {
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),
......@@ -1903,17 +2168,18 @@
},
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);
},
calendar : function () {
calendar : function (time) {
// We want to compare the start of today, vs this.
// Getting start-of-today depends on whether we're zone'd or not.
var sod = makeAs(moment(), this).startOf('day'),
var now = time || moment(),
sod = makeAs(now, this).startOf('day'),
diff = this.diff(sod, 'days', true),
format = diff < -6 ? 'sameElse' :
diff < -1 ? 'lastWeek' :
......@@ -1921,7 +2187,7 @@
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 () {
......@@ -1936,38 +2202,16 @@
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 : function (input) {
var utc = this._isUTC ? 'UTC' : '',
dayOfMonth;
if (input != null) {
if (typeof input === 'string') {
input = this.lang().monthsParse(input);
if (typeof input !== 'number') {
return this;
}
}
dayOfMonth = this.date();
this.date(1);
this._d['set' + utc + 'Month'](input);
this.date(Math.min(dayOfMonth, this.daysInMonth()));
moment.updateOffset(this);
return this;
} else {
return this._d['get' + utc + 'Month']();
}
},
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.
......@@ -1975,6 +2219,7 @@
case 'year':
this.month(0);
/* falls through */
case 'quarter':
case 'month':
this.date(1);
/* falls through */
......@@ -2001,12 +2246,17 @@
this.isoWeekday(1);
}
// quarters are also special
if (units === 'quarter') {
this.month(Math.floor(this.month() / 3) * 3);
}
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) {
......@@ -2024,29 +2274,59 @@
return +this.clone().startOf(units) === +makeAs(input, this).startOf(units);
},
min: function (other) {
other = moment.apply(null, arguments);
return other < this ? this : other;
},
max: function (other) {
other = moment.apply(null, arguments);
return other > this ? this : other;
},
min: deprecate(
'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;
}
),
zone : function (input) {
var offset = this._offset || 0;
max: deprecate(
'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;
}
),
// 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, 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) {
addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, true);
if (!keepLocalTime || this._changeInProgress) {
addOrSubtractDurationFromMoment(this,
moment.duration(offset - input, 'm'), 1, false);
} else if (!this._changeInProgress) {
this._changeInProgress = true;
moment.updateOffset(this, true);
this._changeInProgress = null;
}
}
} else {
return this._isUTC ? offset : this._d.getTimezoneOffset();
......@@ -2055,11 +2335,11 @@
},
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 () {
......@@ -2088,36 +2368,36 @@
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 () {
return Math.ceil((this.month() + 1.0) / 3.0);
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) {
......@@ -2127,6 +2407,15 @@
return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
},
isoWeeksInYear : function () {
return weeksInYear(this.year(), 1, 4);
},
weeksInYear : function () {
var weekInfo = this.localeData()._week;
return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
},
get : function (units) {
units = normalizeUnits(units);
return this[units]();
......@@ -2140,46 +2429,97 @@
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;
}
});
// helper for adding shortcuts
function makeGetterAndSetter(name, key) {
moment.fn[name] = moment.fn[name + 's'] = function (input) {
var utc = this._isUTC ? 'UTC' : '';
if (input != null) {
this._d['set' + utc + key](input);
moment.updateOffset(this);
function rawMonthSetter(mom, value) {
var dayOfMonth;
// TODO: Move this out of here!
if (typeof value === 'string') {
value = mom.localeData().monthsParse(value);
// TODO: Another silent failure?
if (typeof value !== 'number') {
return mom;
}
}
dayOfMonth = Math.min(mom.date(),
daysInMonth(mom.year(), value));
mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
return mom;
}
function rawGetter(mom, unit) {
return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
}
function rawSetter(mom, unit, value) {
if (unit === 'Month') {
return rawMonthSetter(mom, value);
} else {
return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
}
}
function makeAccessor(unit, keepTime) {
return function (value) {
if (value != null) {
rawSetter(this, unit, value);
moment.updateOffset(this, keepTime);
return this;
} else {
return this._d['get' + utc + key]();
return rawGetter(this, unit);
}
};
}
// loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds)
for (i = 0; i < proxyGettersAndSetters.length; i ++) {
makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase().replace(/s$/, ''), proxyGettersAndSetters[i]);
}
// add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear')
makeGetterAndSetter('year', 'FullYear');
moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false);
moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false);
moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false);
// Setting the hour should keep the time, because the user explicitly
// specified which hour he wants. So trying to maintain the same hour (in
// 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.year = 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;
moment.fn.isoWeeks = moment.fn.isoWeek;
moment.fn.quarters = moment.fn.quarter;
// add aliased format methods
moment.fn.toJSON = moment.fn.toISOString;
......@@ -2189,6 +2529,17 @@
************************************/
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 () {
......@@ -2196,7 +2547,7 @@
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.
......@@ -2212,15 +2563,40 @@
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);
},
......@@ -2233,14 +2609,13 @@
},
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) {
......@@ -2274,13 +2649,39 @@
},
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()),
......@@ -2304,6 +2705,10 @@
(hours ? hours + 'H' : '') +
(minutes ? minutes + 'M' : '') +
(seconds ? seconds + 'S' : '');
},
localeData : function () {
return this._locale;
}
});
......@@ -2313,32 +2718,44 @@
};
}
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]);
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' :
......@@ -2349,52 +2766,43 @@
}
});
/* EMBED_LANGUAGES */
/* EMBED_LOCALES */
/************************************
Exposing Moment
************************************/
function makeGlobal(deprecate) {
var warned = false, local_moment = moment;
function makeGlobal(shouldDeprecate) {
/*global ender:false */
if (typeof ender !== 'undefined') {
return;
}
// here, `this` means `window` in the browser, or `global` on the server
// add `moment` as a global object via a string identifier,
// for Closure Compiler "advanced" mode
if (deprecate) {
global.moment = function () {
if (!warned && console && console.warn) {
warned = true;
console.warn(
"Accessing Moment through the global scope is " +
"deprecated, and will be removed in an upcoming " +
"release.");
}
return local_moment.apply(null, arguments);
};
extend(global.moment, local_moment);
oldGlobalMoment = globalScope.moment;
if (shouldDeprecate) {
globalScope.moment = deprecate(
'Accessing Moment through the global scope is ' +
'deprecated, and will be removed in an upcoming ' +
'release.',
moment);
} else {
global['moment'] = moment;
globalScope.moment = moment;
}
}
// CommonJS module is defined
if (hasModule) {
module.exports = moment;
makeGlobal(true);
} else if (typeof define === "function" && define.amd) {
define("moment", function (require, exports, module) {
if (module.config && module.config() && module.config().noGlobal !== true) {
// If user provided noGlobal, he is aware of global
makeGlobal(module.config().noGlobal === undefined);
} 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;
}
return moment;
});
makeGlobal(true);
} else {
makeGlobal();
}
}).call(this);
\ No newline at end of file
}).call(this);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment