diff --git a/src/UI/Handlebars/Helpers/DateTime.js b/src/UI/Handlebars/Helpers/DateTime.js index b364678a0..8033a4d88 100644 --- a/src/UI/Handlebars/Helpers/DateTime.js +++ b/src/UI/Handlebars/Helpers/DateTime.js @@ -69,6 +69,6 @@ define( return ''; } - return moment(input).format('LTS'); + return moment(input).format('h:mm:ss A'); }); }); diff --git a/src/UI/JsLibraries/moment.js b/src/UI/JsLibraries/moment.js index 85e190d4a..83282c6fd 100644 --- a/src/UI/JsLibraries/moment.js +++ b/src/UI/JsLibraries/moment.js @@ -1,21 +1,21 @@ //! moment.js -//! version : 2.8.4 +//! version : 2.7.0 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT //! momentjs.com (function (undefined) { + /************************************ Constants ************************************/ var moment, - VERSION = '2.8.4', + VERSION = "2.7.0", // 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, @@ -26,14 +26,25 @@ SECOND = 5, MILLISECOND = 6, - // internal storage for locale config files - locales = {}, + // internal storage for language config files + languages = {}, - // extra moment internal properties (plugins register props here) - momentProperties = [], + // 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 + }, // check for nodeJS - hasModule = (typeof module !== 'undefined' && module && module.exports), + hasModule = (typeof module !== 'undefined' && module.exports), // ASP.NET json date format regex aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, @@ -44,8 +55,8 @@ 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]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g, - localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/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 parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99 @@ -56,8 +67,8 @@ parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic. parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z parseTokenT = /T/i, // T (ISO separator) - parseTokenOffsetMs = /[\+\-]?\d+/, // 1234567890123 parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 + parseTokenOrdinal = /\d{1,2}/, //strict parsing regexes parseTokenOneDigit = /\d/, // 0 - 9 @@ -89,7 +100,7 @@ ['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 @@ -136,11 +147,12 @@ // 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 + 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 }, // tokens to ordinalize and pad @@ -152,10 +164,10 @@ return this.month() + 1; }, MMM : function (format) { - return this.localeData().monthsShort(this, format); + return this.lang().monthsShort(this, format); }, MMMM : function (format) { - return this.localeData().months(this, format); + return this.lang().months(this, format); }, D : function () { return this.date(); @@ -167,13 +179,13 @@ return this.day(); }, dd : function (format) { - return this.localeData().weekdaysMin(this, format); + return this.lang().weekdaysMin(this, format); }, ddd : function (format) { - return this.localeData().weekdaysShort(this, format); + return this.lang().weekdaysShort(this, format); }, dddd : function (format) { - return this.localeData().weekdays(this, format); + return this.lang().weekdays(this, format); }, w : function () { return this.week(); @@ -219,10 +231,10 @@ return this.isoWeekday(); }, a : function () { - return this.localeData().meridiem(this.hours(), this.minutes(), true); + return this.lang().meridiem(this.hours(), this.minutes(), true); }, A : function () { - return this.localeData().meridiem(this.hours(), this.minutes(), false); + return this.lang().meridiem(this.hours(), this.minutes(), false); }, H : function () { return this.hours(); @@ -250,19 +262,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); }, @@ -272,9 +284,6 @@ zz : function () { return this.zoneName(); }, - x : function () { - return this.valueOf(); - }, X : function () { return this.unix(); }, @@ -283,8 +292,6 @@ } }, - deprecations = {}, - lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin']; // Pick the first defined of two or three arguments. dfl comes from @@ -293,14 +300,10 @@ 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. @@ -318,31 +321,23 @@ }; } - 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(msg); + printMsg(); 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); @@ -350,7 +345,7 @@ } function ordinalizeToken(func, period) { return function (a) { - return this.localeData().ordinal(func.call(this, a), period); + return this.lang().ordinal(func.call(this, a), period); }; } @@ -369,16 +364,14 @@ Constructors ************************************/ - function Locale() { + function Language() { + } // Moment prototype object - function Moment(config, skipOverflow) { - if (skipOverflow !== false) { - checkOverflow(config); - } - copyConfig(this, config); - this._d = new Date(+config._d); + function Moment(config) { + checkOverflow(config); + extend(this, config); } // Duration Constructor @@ -412,8 +405,6 @@ this._data = {}; - this._locale = moment.localeData(); - this._bubble(); } @@ -424,67 +415,31 @@ function extend(a, b) { for (var i in b) { - if (hasOwnProp(b, i)) { + if (b.hasOwnProperty(i)) { a[i] = b[i]; } } - if (hasOwnProp(b, 'toString')) { + if (b.hasOwnProperty("toString")) { a.toString = b.toString; } - if (hasOwnProp(b, 'valueOf')) { + if (b.hasOwnProperty("valueOf")) { a.valueOf = b.valueOf; } return a; } - 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; - } + function cloneMoment(m) { + var result = {}, i; + for (i in m) { + if (m.hasOwnProperty(i) && momentProperties.hasOwnProperty(i)) { + result[i] = m[i]; } } - return to; + return result; } function absRound(number) { @@ -507,51 +462,7 @@ return (sign ? (forceSign ? '+' : '') : '-') + output; } - 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; - }; - } - + // helper function for _.addTime and _.subtractTime function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) { var milliseconds = duration._milliseconds, days = duration._days, @@ -578,8 +489,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 @@ -611,7 +522,7 @@ prop; for (prop in inputObject) { - if (hasOwnProp(inputObject, prop)) { + if (inputObject.hasOwnProperty(prop)) { normalizedProp = normalizeUnits(prop); if (normalizedProp) { normalizedInput[normalizedProp] = inputObject[prop]; @@ -639,7 +550,7 @@ moment[field] = function (format, index) { var i, getter, - method = moment._locale[field], + method = moment.fn._lang[field], results = []; if (typeof format === 'number') { @@ -649,7 +560,7 @@ getter = function (i) { var m = moment().utc().set(setter, i); - return method.call(moment._locale, m, format || ''); + return method.call(moment.fn._lang, m, format || ''); }; if (index != null) { @@ -701,10 +612,7 @@ overflow = m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH : m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE : - m._a[HOUR] < 0 || m._a[HOUR] > 24 || - (m._a[HOUR] === 24 && (m._a[MINUTE] !== 0 || - m._a[SECOND] !== 0 || - m._a[MILLISECOND] !== 0)) ? HOUR : + m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR : m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE : m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND : m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND : @@ -731,79 +639,28 @@ if (m._strict) { m._isValid = m._isValid && m._pf.charsLeftOver === 0 && - m._pf.unusedTokens.length === 0 && - m._pf.bigHour === undefined; + m._pf.unusedTokens.length === 0; } } return m._isValid; } - function normalizeLocale(key) { + function normalizeLanguage(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) { - var res, diff; - if (model._isUTC) { - res = model.clone(); - diff = (moment.isMoment(input) || isDate(input) ? - +input : +moment(input)) - (+res); - // Use low-level api, because this fn is low-level api. - res._d.setTime(+res._d + diff); - moment.updateOffset(res, false); - return res; - } else { - return moment(input).local(); - } + return model._isUTC ? moment(input).zone(model._offset || 0) : + moment(input).local(); } /************************************ - Locale + Languages ************************************/ - extend(Locale.prototype, { + extend(Language.prototype, { set : function (config) { var prop, i; @@ -815,63 +672,50 @@ this['_' + i] = prop; } } - // Lenient ordinal parsing accepts just a number in addition to - // number + (possibly) stuff coming from _ordinalParseLenient. - this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\d{1,2}/.source); }, - _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, format, strict) { + monthsParse : function (monthName) { var i, mom, regex; if (!this._monthsParse) { this._monthsParse = []; - this._longMonthsParse = []; - this._shortMonthsParse = []; } for (i = 0; i < 12; i++) { // make the regex if we don't have it already - mom = moment.utc([2000, i]); - if (strict && !this._longMonthsParse[i]) { - this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); - this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); - } - if (!strict && !this._monthsParse[i]) { + if (!this._monthsParse[i]) { + mom = moment.utc([2000, i]); regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); } // test the regex - if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { - return i; - } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { - return i; - } else if (!strict && this._monthsParse[i].test(monthName)) { + if (this._monthsParse[i].test(monthName)) { 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()]; }, @@ -898,12 +742,11 @@ }, _longDateFormat : { - LTS : 'h:mm:ss A', - 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]; @@ -939,44 +782,41 @@ lastWeek : '[Last] dddd [at] LT', sameElse : 'L' }, - calendar : function (key, mom, now) { + calendar : function (key, mom) { var output = this._calendar[key]; - return typeof output === 'function' ? output.apply(mom, [now]) : output; + 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', - _ordinalParse : /\d{1,2}/, + _ordinal : "%d", preparse : function (string) { return string; @@ -1001,6 +841,78 @@ } }); + // 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 ************************************/ @@ -1008,9 +920,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) { @@ -1025,7 +937,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]; } @@ -1035,11 +947,12 @@ // format date using native date object function formatMoment(m, format) { + if (!m.isValid()) { - return m.localeData().invalidDate(); + return m.lang().invalidDate(); } - format = expandFormat(format, m.localeData()); + format = expandFormat(format, m.lang()); if (!formatFunctions[format]) { formatFunctions[format] = makeFormatFunction(format); @@ -1048,11 +961,11 @@ return formatFunctions[format](m); } - function expandFormat(format, locale) { + function expandFormat(format, lang) { var i = 5; function replaceLongDateFormatTokens(input) { - return locale.longDateFormat(input) || input; + return lang.longDateFormat(input) || input; } localFormattingTokens.lastIndex = 0; @@ -1093,19 +1006,13 @@ 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; @@ -1117,9 +1024,7 @@ return parseTokenWord; case 'a': case 'A': - return config._locale._meridiemParse; - case 'x': - return parseTokenOffsetMs; + return getLangDefinition(config._l)._meridiemParse; case 'X': return parseTokenTimestampMs; case 'Z': @@ -1154,15 +1059,15 @@ case 'E': return parseTokenOneOrTwoDigits; case 'Do': - return strict ? config._locale._ordinalParse : config._locale._ordinalParseLenient; + 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], @@ -1191,7 +1096,7 @@ break; case 'MMM' : // fall through to MMMM case 'MMMM' : - a = config._locale.monthsParse(input, token, config._strict); + a = getLangDefinition(config._l).monthsParse(input); // if we didn't find a month name, mark the date as invalid. if (a != null) { datePartArray[MONTH] = a; @@ -1208,8 +1113,7 @@ break; case 'Do' : if (input != null) { - datePartArray[DATE] = toInt(parseInt( - input.match(/\d{1,2}/)[0], 10)); + datePartArray[DATE] = toInt(parseInt(input, 10)); } break; // DAY OF YEAR @@ -1232,15 +1136,13 @@ // AM / PM case 'a' : // fall through to A case 'A' : - config._isPm = config._locale.isPM(input); + config._isPm = getLangDefinition(config._l).isPM(input); break; - // HOUR + // 24 HOUR + case 'H' : // fall through to hh + case 'HH' : // fall through to hh case 'h' : // fall through to hh case 'hh' : - config._pf.bigHour = true; - /* falls through */ - case 'H' : // fall through to HH - case 'HH' : datePartArray[HOUR] = toInt(input); break; // MINUTE @@ -1260,10 +1162,6 @@ case 'SSSS' : datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000); break; - // UNIX OFFSET (MILLISECONDS) - case 'x': - config._d = new Date(toInt(input)); - break; // UNIX TIMESTAMP WITH MS case 'X': config._d = new Date(parseFloat(input) * 1000); @@ -1278,7 +1176,7 @@ case 'dd': case 'ddd': case 'dddd': - a = config._locale.weekdaysParse(input); + a = getLangDefinition(config._l).weekdaysParse(input); // if we didn't get a weekday name, mark the date as invalid if (a != null) { config._w = config._w || {}; @@ -1314,7 +1212,7 @@ } function dayOfYearFromWeekInfo(config) { - var w, weekYear, week, weekday, dow, doy, temp; + var w, weekYear, week, weekday, dow, doy, temp, lang; w = config._w; if (w.GG != null || w.W != null || w.E != null) { @@ -1329,8 +1227,9 @@ week = dfl(w.W, 1); weekday = dfl(w.E, 1); } else { - dow = config._locale._week.dow; - doy = config._locale._week.doy; + lang = getLangDefinition(config._l); + dow = lang._week.dow; + doy = lang._week.doy; weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year); week = dfl(w.w, 1); @@ -1400,25 +1299,12 @@ config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; } - // Check for 24:00:00.000 - if (config._a[HOUR] === 24 && - config._a[MINUTE] === 0 && - config._a[SECOND] === 0 && - config._a[MILLISECOND] === 0) { - config._nextDay = true; - config._a[HOUR] = 0; - } - 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); } - - if (config._nextDay) { - config._a[HOUR] = 24; - } } function dateFromObject(config) { @@ -1432,7 +1318,7 @@ config._a = [ normalizedInput.year, normalizedInput.month, - normalizedInput.day || normalizedInput.date, + normalizedInput.day, normalizedInput.hour, normalizedInput.minute, normalizedInput.second, @@ -1457,6 +1343,7 @@ // date from string and format string function makeDateFromStringAndFormat(config) { + if (config._f === moment.ISO_8601) { parseISO(config); return; @@ -1466,12 +1353,13 @@ config._pf.empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC` - var string = '' + config._i, + var lang = getLangDefinition(config._l), + string = '' + config._i, i, parsedInput, tokens, token, skipped, stringLength = string.length, totalParsedInputLength = 0; - tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; + tokens = expandFormat(config._f, lang).match(formattingTokens) || []; for (i = 0; i < tokens.length; i++) { token = tokens[i]; @@ -1505,10 +1393,6 @@ config._pf.unusedInput.push(string); } - // clear _12h flag if hour is <= 12 - if (config._pf.bigHour === true && config._a[HOUR] <= 12) { - config._pf.bigHour = undefined; - } // handle am pm if (config._isPm && config._a[HOUR] < 12) { config._a[HOUR] += 12; @@ -1517,6 +1401,7 @@ if (config._isPm === false && config._a[HOUR] === 12) { config._a[HOUR] = 0; } + dateFromConfig(config); checkOverflow(config); } @@ -1549,10 +1434,7 @@ for (i = 0; i < config._f.length; i++) { currentScore = 0; - tempConfig = copyConfig({}, config); - if (config._useUTC != null) { - tempConfig._useUTC = config._useUTC; - } + tempConfig = extend({}, config); tempConfig._pf = defaultParsingFlags(); tempConfig._f = config._f[i]; makeDateFromStringAndFormat(tempConfig); @@ -1588,8 +1470,8 @@ 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; } } @@ -1600,7 +1482,7 @@ } } if (string.match(parseTokenTimezone)) { - config._f += 'Z'; + config._f += "Z"; } makeDateFromStringAndFormat(config); } else { @@ -1617,29 +1499,21 @@ } } - function map(arr, fn) { - var res = [], i; - for (i = 0; i < arr.length; ++i) { - res.push(fn(arr[i], i)); - } - return res; - } - function makeDateFromInput(config) { - var input = config._i, matched; + var input = config._i, + matched = aspNetJsonRegex.exec(input); + if (input === undefined) { config._d = new Date(); - } else if (isDate(input)) { - config._d = new Date(+input); - } else if ((matched = aspNetJsonRegex.exec(input)) !== null) { + } else if (matched) { config._d = new Date(+matched[1]); } else if (typeof input === 'string') { makeDateFromString(config); } else if (isArray(input)) { - config._a = map(input.slice(0), function (obj) { - return parseInt(obj, 10); - }); + 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') { @@ -1670,13 +1544,13 @@ return date; } - function parseWeekday(input, locale) { + function parseWeekday(input, language) { if (typeof input === 'string') { if (!isNaN(input)) { input = parseInt(input, 10); } else { - input = locale.weekdaysParse(input); + input = language.weekdaysParse(input); if (typeof input !== 'number') { return null; } @@ -1691,33 +1565,29 @@ // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize - function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { - return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); + function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) { + return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture); } - 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] || + 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] || minutes === 1 && ['m'] || minutes < relativeTimeThresholds.m && ['mm', minutes] || hours === 1 && ['h'] || hours < relativeTimeThresholds.h && ['hh', hours] || days === 1 && ['d'] || - days < relativeTimeThresholds.d && ['dd', days] || - months === 1 && ['M'] || - months < relativeTimeThresholds.M && ['MM', months] || + days <= relativeTimeThresholds.dd && ['dd', days] || + days <= relativeTimeThresholds.dm && ['M'] || + days < relativeTimeThresholds.dy && ['MM', round(days / 30)] || years === 1 && ['y'] || ['yy', years]; - args[2] = withoutSuffix; - args[3] = +posNegDuration > 0; - args[4] = locale; + args[3] = milliseconds > 0; + args[4] = lang; return substituteTimeAgo.apply({}, args); } @@ -1748,7 +1618,7 @@ daysToDayOfWeek += 7; } - adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd'); + adjustedMoment = moment(mom).add('d', daysToDayOfWeek); return { week: Math.ceil(adjustedMoment.dayOfYear() / 7), year: adjustedMoment.year() @@ -1776,21 +1646,20 @@ function makeMoment(config) { var input = config._i, - format = config._f, - res; - - config._locale = config._locale || moment.localeData(config._l); + format = config._f; if (input === null || (format === undefined && input === '')) { return moment.invalid({nullInput: true}); } if (typeof input === 'string') { - config._i = input = config._locale.preparse(input); + config._i = input = getLangDefinition().preparse(input); } if (moment.isMoment(input)) { - return new Moment(input, true); + config = cloneMoment(input); + + config._d = new Date(+input._d); } else if (format) { if (isArray(format)) { makeDateFromStringAndArray(config); @@ -1801,22 +1670,15 @@ makeDateFromInput(config); } - res = new Moment(config); - if (res._nextDay) { - // Adding is smart enough around DST - res.add(1, 'd'); - res._nextDay = undefined; - } - - return res; + return new Moment(config); } - moment = function (input, format, locale, strict) { + moment = function (input, format, lang, strict) { var c; - if (typeof(locale) === 'boolean') { - strict = locale; - locale = undefined; + if (typeof(lang) === "boolean") { + strict = lang; + lang = undefined; } // object construction must be done this way. // https://github.com/moment/moment/issues/1423 @@ -1824,7 +1686,7 @@ c._isAMomentObject = true; c._i = input; c._f = format; - c._l = locale; + c._l = lang; c._strict = strict; c._isUTC = false; c._pf = defaultParsingFlags(); @@ -1835,14 +1697,13 @@ 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 + (config._useUTC ? ' UTC' : '')); - } - ); + "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. @@ -1879,12 +1740,12 @@ }; // creating with utc - moment.utc = function (input, format, locale, strict) { + moment.utc = function (input, format, lang, strict) { var c; - if (typeof(locale) === 'boolean') { - strict = locale; - locale = undefined; + if (typeof(lang) === "boolean") { + strict = lang; + lang = undefined; } // object construction must be done this way. // https://github.com/moment/moment/issues/1423 @@ -1892,7 +1753,7 @@ c._isAMomentObject = true; c._useUTC = true; c._isUTC = true; - c._l = locale; + c._l = lang; c._i = input; c._f = format; c._strict = strict; @@ -1913,8 +1774,7 @@ match = null, sign, ret, - parseIso, - diffRes; + parseIso; if (moment.isDuration(input)) { duration = { @@ -1930,7 +1790,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, @@ -1940,7 +1800,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. @@ -1958,19 +1818,12 @@ 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) && hasOwnProp(input, '_locale')) { - ret._locale = input._locale; + if (moment.isDuration(input) && input.hasOwnProperty('_lang')) { + ret._lang = input._lang; } return ret; @@ -1994,99 +1847,46 @@ 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; - } - if (limit === undefined) { - return relativeTimeThresholds[threshold]; - } - relativeTimeThresholds[threshold] = limit; - return true; + moment.relativeTimeThreshold = function(threshold, limit) { + if (relativeTimeThresholds[threshold] === undefined) { + return false; + } + 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 + // This function will load languages and then set the global language. If // no arguments are passed in, it will simply return the current global - // 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; - } - }; - - 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; - } - + // language key. + moment.lang = function (key, values) { + var r; if (!key) { - return moment._locale; - } + 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; + }; - if (!isArray(key)) { - //short-circuit everything else - locale = loadLocale(key); - if (locale) { - return locale; - } - key = [key]; + // returns language data + moment.langData = function (key) { + if (key && key._lang && key._lang._abbr) { + key = key._lang._abbr; } - - return chooseLocale(key); + return getLangDefinition(key); }; // compare moment object moment.isMoment = function (obj) { return obj instanceof Moment || - (obj != null && hasOwnProp(obj, '_isAMomentObject')); + (obj != null && obj.hasOwnProperty('_isAMomentObject')); }; // for typechecking Duration objects @@ -2142,7 +1942,7 @@ }, toString : function () { - return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); + return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ"); }, toDate : function () { @@ -2152,12 +1952,7 @@ toISOString : function () { var m = moment(this).utc(); if (0 < m.year() && m.year() <= 9999) { - if ('function' === typeof Date.prototype.toISOString) { - // native implementation is ~50x faster, use it when we can - return this.toDate().toISOString(); - } else { - return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); - } + return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); } else { return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); } @@ -2181,6 +1976,7 @@ }, isDSTShifted : function () { + if (this._a) { return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0; } @@ -2196,35 +1992,53 @@ return this._pf.overflow; }, - utc : function (keepLocalTime) { - return this.zone(0, keepLocalTime); + utc : function () { + return this.zone(0); }, - local : function (keepLocalTime) { - if (this._isUTC) { - this.zone(0, keepLocalTime); - this._isUTC = false; - - if (keepLocalTime) { - this.add(this._dateTzOffset(), 'm'); - } - } + local : function () { + this.zone(0); + this._isUTC = false; return this; }, format : function (inputString) { var output = formatMoment(this, inputString || moment.defaultFormat); - return this.localeData().postformat(output); + return this.lang().postformat(output); }, - add : createAdder(1, 'add'), + 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; + }, - subtract : createAdder(-1, 'subtract'), + 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; + }, diff : function (input, units, asFloat) { var that = makeAs(input, this), zoneDiff = (this.zone() - that.zone()) * 6e4, - diff, output, daysAdjust; + diff, output; units = normalizeUnits(units); @@ -2235,12 +2049,11 @@ output = ((this.year() - that.year()) * 12) + (this.month() - that.month()); // adjust by taking difference in days, average number of days // and dst in the given months. - daysAdjust = (this - moment(this).startOf('month')) - - (that - moment(that).startOf('month')); + output += ((this - moment(this).startOf('month')) - + (that - moment(that).startOf('month'))) / diff; // same as above but with zones, to negate all dst - daysAdjust -= ((this.zone() - moment(this).startOf('month').zone()) - - (that.zone() - moment(that).startOf('month').zone())) * 6e4; - output += daysAdjust / diff; + output -= ((this.zone() - moment(this).startOf('month').zone()) - + (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff; if (units === 'year') { output = output / 12; } @@ -2257,7 +2070,7 @@ }, from : function (time, withoutSuffix) { - return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix); }, fromNow : function (withoutSuffix) { @@ -2276,7 +2089,7 @@ diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse'; - return this.format(this.localeData().calendar(format, this, moment(now))); + return this.format(this.lang().calendar(format, this)); }, isLeapYear : function () { @@ -2291,8 +2104,8 @@ day : function (input) { var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); if (input != null) { - input = parseWeekday(input, this.localeData()); - return this.add(input - day, 'd'); + input = parseWeekday(input, this.lang()); + return this.add({ d : input - day }); } else { return day; } @@ -2300,7 +2113,7 @@ 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. @@ -2345,50 +2158,26 @@ endOf: function (units) { units = normalizeUnits(units); - if (units === undefined || units === 'millisecond') { - return this; - } - return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); + return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1); }, isAfter: function (input, units) { - var inputMs; - units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); - if (units === 'millisecond') { - input = moment.isMoment(input) ? input : moment(input); - return +this > +input; - } else { - inputMs = moment.isMoment(input) ? +input : +moment(input); - return inputMs < +this.clone().startOf(units); - } + units = typeof units !== 'undefined' ? units : 'millisecond'; + return +this.clone().startOf(units) > +moment(input).startOf(units); }, isBefore: function (input, units) { - var inputMs; - units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); - if (units === 'millisecond') { - input = moment.isMoment(input) ? input : moment(input); - return +this < +input; - } else { - inputMs = moment.isMoment(input) ? +input : +moment(input); - return +this.clone().endOf(units) < inputMs; - } + units = typeof units !== 'undefined' ? units : 'millisecond'; + return +this.clone().startOf(units) < +moment(input).startOf(units); }, isSame: function (input, units) { - var inputMs; - units = normalizeUnits(units || 'millisecond'); - if (units === 'millisecond') { - input = moment.isMoment(input) ? input : moment(input); - return +this === +input; - } else { - inputMs = +moment(input); - return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units)); - } + 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; @@ -2396,43 +2185,36 @@ ), 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; } ), - // 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. + // 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. // // 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; + zone : function (input, keepTime) { + var offset = this._offset || 0; 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._dateTzOffset(); - } this._offset = input; this._isUTC = true; - if (localAdjust != null) { - this.subtract(localAdjust, 'm'); - } if (offset !== input) { - if (!keepLocalTime || this._changeInProgress) { + if (!keepTime || this._changeInProgress) { addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, false); } else if (!this._changeInProgress) { @@ -2442,17 +2224,17 @@ } } } else { - return this._isUTC ? offset : this._dateTzOffset(); + return this._isUTC ? offset : this._d.getTimezoneOffset(); } 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 () { @@ -2481,7 +2263,7 @@ dayOfYear : function (input) { var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; - return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); + return input == null ? dayOfYear : this.add("d", (input - dayOfYear)); }, quarter : function (input) { @@ -2489,28 +2271,28 @@ }, weekYear : function (input) { - var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year; - return input == null ? year : this.add((input - year), 'y'); + var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year; + return input == null ? year : this.add("y", (input - year)); }, isoWeekYear : function (input) { var year = weekOfYear(this, 1, 4).year; - return input == null ? year : this.add((input - year), 'y'); + return input == null ? year : this.add("y", (input - year)); }, week : function (input) { - var week = this.localeData().week(this); - return input == null ? week : this.add((input - week) * 7, 'd'); + var week = this.lang().week(this); + return input == null ? week : this.add("d", (input - week) * 7); }, isoWeek : function (input) { var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add((input - week) * 7, 'd'); + return input == null ? week : this.add("d", (input - week) * 7); }, weekday : function (input) { - var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; - return input == null ? weekday : this.add(input - weekday, 'd'); + var weekday = (this.day() + 7 - this.lang()._week.dow) % 7; + return input == null ? weekday : this.add("d", input - weekday); }, isoWeekday : function (input) { @@ -2525,7 +2307,7 @@ }, weeksInYear : function () { - var weekInfo = this.localeData()._week; + var weekInfo = this._lang._week; return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); }, @@ -2542,42 +2324,16 @@ return this; }, - // If passed a locale key, it will set the locale for this - // instance. Otherwise, it will return the locale configuration + // If passed a language key, it will set the language for this + // instance. Otherwise, it will return the language configuration // variables for this instance. - locale : function (key) { - var newLocaleData; - + lang : function (key) { if (key === undefined) { - return this._locale._abbr; + return this._lang; } else { - newLocaleData = moment.localeData(key); - if (newLocaleData != null) { - this._locale = newLocaleData; - } + this._lang = getLangDefinition(key); return this; } - }, - - lang : deprecate( - 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', - function (key) { - if (key === undefined) { - return this.localeData(); - } else { - return this.locale(key); - } - } - ), - - localeData : function () { - return this._locale; - }, - - _dateTzOffset : function () { - // On Firefox.24 Date#getTimezoneOffset returns a floating point. - // https://github.com/moment/moment/pull/1871 - return Math.round(this._d.getTimezoneOffset() / 15) * 15; } }); @@ -2586,7 +2342,7 @@ // TODO: Move this out of here! if (typeof value === 'string') { - value = mom.localeData().monthsParse(value); + value = mom.lang().monthsParse(value); // TODO: Another silent failure? if (typeof value !== 'number') { return mom; @@ -2633,9 +2389,9 @@ 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; @@ -2652,17 +2408,6 @@ ************************************/ - 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 () { @@ -2670,7 +2415,7 @@ days = this._days, months = this._months, data = this._data, - seconds, minutes, hours, years = 0; + seconds, minutes, hours, years; // The following code bubbles up values, see the tests for // examples of what that means. @@ -2686,40 +2431,15 @@ 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); - days %= 30; + data.months = months % 12; - // 12 months -> 1 year - years += absRound(months / 12); - months %= 12; - - data.days = days; - data.months = months; + years = absRound(months / 12); 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); }, @@ -2732,13 +2452,14 @@ }, humanize : function (withSuffix) { - var output = relativeTime(this, !withSuffix, this.localeData()); + var difference = +this, + output = relativeTime(difference, !withSuffix, this.lang()); if (withSuffix) { - output = this.localeData().pastFuture(+this, output); + output = this.lang().pastFuture(difference, output); } - return this.localeData().postformat(output); + return this.lang().postformat(output); }, add : function (input, val) { @@ -2772,41 +2493,13 @@ }, as : function (units) { - var days, months; units = normalizeUnits(units); - - if (units === 'month' || units === 'year') { - days = this._days + this._milliseconds / 864e5; - months = this._months + daysToYears(days) * 12; - return units === 'month' ? months : months / 12; - } else { - // handle milliseconds separately because of floating point math errors (issue #1867) - days = this._days + Math.round(yearsToDays(this._months / 12)); - switch (units) { - case 'week': return days / 7 + this._milliseconds / 6048e5; - case 'day': return days + this._milliseconds / 864e5; - case 'hour': return days * 24 + this._milliseconds / 36e5; - case 'minute': return days * 24 * 60 + this._milliseconds / 6e4; - case 'second': return days * 24 * 60 * 60 + this._milliseconds / 1000; - // Math.floor prevents floating point math errors here - case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds; - default: throw new Error('Unknown unit ' + units); - } - } + return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's'](); }, lang : moment.fn.lang, - locale : moment.fn.locale, - - toIsoString : deprecate( - 'toIsoString() is deprecated. Please use toISOString() instead ' + - '(notice the capitals)', - function () { - return this.toISOString(); - } - ), - toISOString : function () { + 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()), @@ -2830,60 +2523,41 @@ (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 (hasOwnProp(unitMillisecondFactors, i)) { + if (unitMillisecondFactors.hasOwnProperty(i)) { + makeDurationAsGetter(i, unitMillisecondFactors[i]); makeDurationGetter(i.toLowerCase()); } } - 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'); - }; + makeDurationAsGetter('Weeks', 6048e5); moment.duration.fn.asMonths = function () { - return this.as('M'); - }; - moment.duration.fn.asYears = function () { - return this.as('y'); + return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12; }; + /************************************ - Default Locale + Default Lang ************************************/ - // Set default locale, other locale will inherit from English. - moment.locale('en', { - ordinalParse: /\d{1,2}(th|st|nd|rd)/, + // Set default language, other languages will inherit from English. + moment.lang('en', { ordinal : function (number) { var b = number % 10, output = (toInt(number % 100 / 10) === 1) ? 'th' : @@ -2894,7 +2568,7 @@ } }); - /* EMBED_LOCALES */ + /* EMBED_LANGUAGES */ /************************************ Exposing Moment @@ -2908,9 +2582,9 @@ 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; @@ -2920,8 +2594,8 @@ // 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; diff --git a/src/UI/Release/AgeCell.js b/src/UI/Release/AgeCell.js index 92864bcc4..6462786c3 100644 --- a/src/UI/Release/AgeCell.js +++ b/src/UI/Release/AgeCell.js @@ -13,7 +13,7 @@ define( var age = this.model.get('age'); var ageHours = this.model.get('ageHours'); var published = moment(this.model.get('publishDate')); - var publishedFormatted = published.format('{0} LTS'.format(UiSettings.get('shortDateFormat'))); + var publishedFormatted = published.format('{0} h:mm:ss A'.format(UiSettings.get('shortDateFormat'))); var formatted = age; var suffix = this.plural(age, 'day');