summaryrefslogtreecommitdiffstats
path: root/js/vendor/momentjs/moment.js
diff options
context:
space:
mode:
authorBernhard Posselt <dev@bernhard-posselt.com>2014-03-14 10:22:09 +0100
committerBernhard Posselt <dev@bernhard-posselt.com>2014-03-26 01:34:31 +0100
commit2fc5ca4f601174a7ecb7c77a7059f5fac2ab4611 (patch)
treeaa7ab66e29fc7de98533d1e55832ca4fbcd39611 /js/vendor/momentjs/moment.js
parent22fc777ce7403d706649cf83bb23010dfd7dea04 (diff)
update a lot of stuff, WIP
Diffstat (limited to 'js/vendor/momentjs/moment.js')
-rw-r--r--js/vendor/momentjs/moment.js1188
1 files changed, 963 insertions, 225 deletions
diff --git a/js/vendor/momentjs/moment.js b/js/vendor/momentjs/moment.js
index c8a870e8c..b79da7f26 100644
--- a/js/vendor/momentjs/moment.js
+++ b/js/vendor/momentjs/moment.js
@@ -1,8 +1,8 @@
-// moment.js
-// version : 2.1.0
-// author : Tim Wood
-// license : MIT
-// momentjs.com
+//! moment.js
+//! version : 2.5.1
+//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
+//! license : MIT
+//! momentjs.com
(function (undefined) {
@@ -11,41 +11,86 @@
************************************/
var moment,
- VERSION = "2.1.0",
- round = Math.round, i,
+ VERSION = "2.5.1",
+ global = this,
+ round = Math.round,
+ i,
+
+ YEAR = 0,
+ MONTH = 1,
+ DATE = 2,
+ HOUR = 3,
+ MINUTE = 4,
+ SECOND = 5,
+ MILLISECOND = 6,
+
// internal storage for language config files
languages = {},
+ // 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
+ },
+
// check for nodeJS
- hasModule = (typeof module !== 'undefined' && module.exports),
+ hasModule = (typeof module !== 'undefined' && module.exports && typeof require !== 'undefined'),
// ASP.NET json date format regex
aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
- aspNetTimeSpanJsonRegex = /(\-)?(\d*)?\.?(\d+)\:(\d+)\:(\d+)\.?(\d{3})?/,
+ aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,
+
+ // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
+ // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
+ 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]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,
+ 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,
localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
// parsing token regexes
parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99
parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999
- parseTokenThreeDigits = /\d{3}/, // 000 - 999
- parseTokenFourDigits = /\d{1,4}/, // 0 - 9999
- parseTokenSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
+ parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999
+ parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
+ parseTokenDigits = /\d+/, // nonzero number of digits
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/i, // +00:00 -00:00 +0000 -0000 or Z
- parseTokenT = /T/i, // T (ISO seperator)
+ 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
- // preliminary iso regex
- // 0000-00-00 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000
- isoRegex = /^\s*\d{4}-\d\d-\d\d((T| )(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,
+ //strict parsing regexes
+ parseTokenOneDigit = /\d/, // 0 - 9
+ parseTokenTwoDigits = /\d\d/, // 00 - 99
+ parseTokenThreeDigits = /\d{3}/, // 000 - 999
+ parseTokenFourDigits = /\d{4}/, // 0000 - 9999
+ parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999
+ parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf
+
+ // iso 8601 regex
+ // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
+ isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
+
isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
+ isoDates = [
+ ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
+ ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
+ ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
+ ['GGGG-[W]WW', /\d{4}-W\d{2}/],
+ ['YYYY-DDD', /\d{4}-\d{3}/]
+ ],
+
// iso time formats and regexes
isoTimes = [
- ['HH:mm:ss.S', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/],
+ ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/],
['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
['HH:mm', /(T| )\d\d:\d\d/],
['HH', /(T| )\d\d/]
@@ -72,9 +117,24 @@
m : 'minute',
h : 'hour',
d : 'day',
+ D : 'date',
w : 'week',
+ W : 'isoWeek',
M : 'month',
- y : 'year'
+ y : 'year',
+ DDD : 'dayOfYear',
+ e : 'weekday',
+ E : 'isoWeekday',
+ gg: 'weekYear',
+ GG: 'isoWeekYear'
+ },
+
+ camelFunctions = {
+ dayofyear : 'dayOfYear',
+ isoweekday : 'isoWeekday',
+ isoweek : 'isoWeek',
+ weekyear : 'weekYear',
+ isoweekyear : 'isoWeekYear'
},
// format function strings
@@ -127,11 +187,15 @@
YYYYY : function () {
return leftZeroFill(this.year(), 5);
},
+ YYYYYY : function () {
+ var y = this.year(), sign = y >= 0 ? '+' : '-';
+ return sign + leftZeroFill(Math.abs(y), 6);
+ },
gg : function () {
return leftZeroFill(this.weekYear() % 100, 2);
},
gggg : function () {
- return this.weekYear();
+ return leftZeroFill(this.weekYear(), 4);
},
ggggg : function () {
return leftZeroFill(this.weekYear(), 5);
@@ -140,7 +204,7 @@
return leftZeroFill(this.isoWeekYear() % 100, 2);
},
GGGG : function () {
- return this.isoWeekYear();
+ return leftZeroFill(this.isoWeekYear(), 4);
},
GGGGG : function () {
return leftZeroFill(this.isoWeekYear(), 5);
@@ -170,14 +234,17 @@
return this.seconds();
},
S : function () {
- return ~~(this.milliseconds() / 100);
+ return toInt(this.milliseconds() / 100);
},
SS : function () {
- return leftZeroFill(~~(this.milliseconds() / 10), 2);
+ return leftZeroFill(toInt(this.milliseconds() / 10), 2);
},
SSS : function () {
return leftZeroFill(this.milliseconds(), 3);
},
+ SSSS : function () {
+ return leftZeroFill(this.milliseconds(), 3);
+ },
Z : function () {
var a = -this.zone(),
b = "+";
@@ -185,7 +252,7 @@
a = -a;
b = "-";
}
- return b + leftZeroFill(~~(a / 60), 2) + ":" + leftZeroFill(~~a % 60, 2);
+ return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2);
},
ZZ : function () {
var a = -this.zone(),
@@ -194,7 +261,7 @@
a = -a;
b = "-";
}
- return b + leftZeroFill(~~(10 * a / 6), 4);
+ return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
},
z : function () {
return this.zoneAbbr();
@@ -204,8 +271,30 @@
},
X : function () {
return this.unix();
+ },
+ Q : function () {
+ return this.quarter();
}
+ },
+
+ lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'];
+
+ function defaultParsingFlags() {
+ // We need to deep clone this object, and es5 standard is not very
+ // helpful.
+ return {
+ empty : false,
+ unusedTokens : [],
+ unusedInput : [],
+ overflow : -2,
+ charsLeftOver : 0,
+ nullInput : false,
+ invalidMonth : null,
+ invalidFormat : false,
+ userInvalidated : false,
+ iso: false
};
+ }
function padToken(func, count) {
return function (a) {
@@ -239,36 +328,35 @@
// Moment prototype object
function Moment(config) {
+ checkOverflow(config);
extend(this, config);
}
// Duration Constructor
function Duration(duration) {
- var years = duration.years || duration.year || duration.y || 0,
- months = duration.months || duration.month || duration.M || 0,
- weeks = duration.weeks || duration.week || duration.w || 0,
- days = duration.days || duration.day || duration.d || 0,
- hours = duration.hours || duration.hour || duration.h || 0,
- minutes = duration.minutes || duration.minute || duration.m || 0,
- seconds = duration.seconds || duration.second || duration.s || 0,
- milliseconds = duration.milliseconds || duration.millisecond || duration.ms || 0;
-
- // store reference to input for deterministic cloning
- this._input = duration;
+ var normalizedInput = normalizeObjectUnits(duration),
+ years = normalizedInput.year || 0,
+ months = normalizedInput.month || 0,
+ weeks = normalizedInput.week || 0,
+ days = normalizedInput.day || 0,
+ hours = normalizedInput.hour || 0,
+ minutes = normalizedInput.minute || 0,
+ seconds = normalizedInput.second || 0,
+ milliseconds = normalizedInput.millisecond || 0;
// representation for dateAddRemove
- this._milliseconds = milliseconds +
+ this._milliseconds = +milliseconds +
seconds * 1e3 + // 1000
minutes * 6e4 + // 1000 * 60
hours * 36e5; // 1000 * 60 * 60
// Because of dateAddRemove treats 24 hours as different from a
// day when working around DST, we need to store them separately
- this._days = days +
+ this._days = +days +
weeks * 7;
// It is impossible translate months into days without knowing
// which months you are are talking about, so we have to store
// it separately.
- this._months = months +
+ this._months = +months +
years * 12;
this._data = {};
@@ -276,7 +364,6 @@
this._bubble();
}
-
/************************************
Helpers
************************************/
@@ -288,9 +375,29 @@
a[i] = b[i];
}
}
+
+ if (b.hasOwnProperty("toString")) {
+ a.toString = b.toString;
+ }
+
+ 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];
+ }
+ }
+
+ return result;
+ }
+
function absRound(number) {
if (number < 0) {
return Math.ceil(number);
@@ -301,12 +408,14 @@
// left zero fill a number
// see http://jsperf.com/left-zero-filling for performance comparison
- function leftZeroFill(number, targetLength) {
- var output = number + '';
+ function leftZeroFill(number, targetLength, forceSign) {
+ var output = '' + Math.abs(number),
+ sign = number >= 0;
+
while (output.length < targetLength) {
output = '0' + output;
}
- return output;
+ return (sign ? (forceSign ? '+' : '') : '-') + output;
}
// helper function for _.addTime and _.subtractTime
@@ -315,8 +424,7 @@
days = duration._days,
months = duration._months,
minutes,
- hours,
- currentDate;
+ hours;
if (milliseconds) {
mom._d.setTime(+mom._d + milliseconds * isAdding);
@@ -347,14 +455,20 @@
return Object.prototype.toString.call(input) === '[object Array]';
}
+ function isDate(input) {
+ return Object.prototype.toString.call(input) === '[object Date]' ||
+ input instanceof Date;
+ }
+
// compare two arrays, return the number of differences
- function compareArrays(array1, array2) {
+ function compareArrays(array1, array2, dontConvert) {
var len = Math.min(array1.length, array2.length),
lengthDiff = Math.abs(array1.length - array2.length),
diffs = 0,
i;
for (i = 0; i < len; i++) {
- if (~~array1[i] !== ~~array2[i]) {
+ if ((dontConvert && array1[i] !== array2[i]) ||
+ (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
diffs++;
}
}
@@ -362,16 +476,155 @@
}
function normalizeUnits(units) {
- return units ? unitAliases[units] || units.toLowerCase().replace(/(.)s$/, '$1') : units;
+ if (units) {
+ var lowered = units.toLowerCase().replace(/(.)s$/, '$1');
+ units = unitAliases[units] || camelFunctions[lowered] || lowered;
+ }
+ return units;
}
+ function normalizeObjectUnits(inputObject) {
+ var normalizedInput = {},
+ normalizedProp,
+ prop;
+
+ for (prop in inputObject) {
+ if (inputObject.hasOwnProperty(prop)) {
+ normalizedProp = normalizeUnits(prop);
+ if (normalizedProp) {
+ normalizedInput[normalizedProp] = inputObject[prop];
+ }
+ }
+ }
+
+ return normalizedInput;
+ }
+
+ function makeList(field) {
+ var count, setter;
+
+ if (field.indexOf('week') === 0) {
+ count = 7;
+ setter = 'day';
+ }
+ else if (field.indexOf('month') === 0) {
+ count = 12;
+ setter = 'month';
+ }
+ else {
+ return;
+ }
+
+ moment[field] = function (format, index) {
+ var i, getter,
+ method = moment.fn._lang[field],
+ results = [];
+
+ if (typeof format === 'number') {
+ index = format;
+ format = undefined;
+ }
+
+ getter = function (i) {
+ var m = moment().utc().set(setter, i);
+ return method.call(moment.fn._lang, m, format || '');
+ };
+
+ if (index != null) {
+ return getter(index);
+ }
+ else {
+ for (i = 0; i < count; i++) {
+ results.push(getter(i));
+ }
+ return results;
+ }
+ };
+ }
+
+ function toInt(argumentForCoercion) {
+ var coercedNumber = +argumentForCoercion,
+ value = 0;
+
+ if (coercedNumber !== 0 && isFinite(coercedNumber)) {
+ if (coercedNumber >= 0) {
+ value = Math.floor(coercedNumber);
+ } else {
+ value = Math.ceil(coercedNumber);
+ }
+ }
+
+ return value;
+ }
+
+ function daysInMonth(year, month) {
+ return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
+ }
+
+ function daysInYear(year) {
+ return isLeapYear(year) ? 366 : 365;
+ }
+
+ function isLeapYear(year) {
+ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
+ }
+
+ function checkOverflow(m) {
+ var overflow;
+ if (m._a && m._pf.overflow === -2) {
+ 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] > 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 :
+ -1;
+
+ if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
+ overflow = DATE;
+ }
+
+ m._pf.overflow = overflow;
+ }
+ }
+
+ function isValid(m) {
+ if (m._isValid == null) {
+ m._isValid = !isNaN(m._d.getTime()) &&
+ m._pf.overflow < 0 &&
+ !m._pf.empty &&
+ !m._pf.invalidMonth &&
+ !m._pf.nullInput &&
+ !m._pf.invalidFormat &&
+ !m._pf.userInvalidated;
+
+ if (m._strict) {
+ m._isValid = m._isValid &&
+ m._pf.charsLeftOver === 0 &&
+ m._pf.unusedTokens.length === 0;
+ }
+ }
+ return m._isValid;
+ }
+
+ function normalizeLanguage(key) {
+ return key ? key.toLowerCase().replace('_', '-') : key;
+ }
+
+ // Return a moment from input, that is local/utc/zone equivalent to model.
+ function makeAs(input, model) {
+ return model._isUTC ? moment(input).zone(model._offset || 0) :
+ moment(input).local();
+ }
/************************************
Languages
************************************/
- Language.prototype = {
+ extend(Language.prototype, {
+
set : function (config) {
var prop, i;
for (i in config) {
@@ -404,7 +657,7 @@
for (i = 0; i < 12; i++) {
// make the regex if we don't have it already
if (!this._monthsParse[i]) {
- mom = moment([2000, i]);
+ mom = moment.utc([2000, i]);
regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
}
@@ -470,7 +723,9 @@
},
isPM : function (input) {
- return ((input + '').toLowerCase()[0] === 'p');
+ // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
+ // Using charAt should be more compatible.
+ return ((input + '').toLowerCase().charAt(0) === 'p');
},
_meridiemParse : /[ap]\.?m?\.?/i,
@@ -537,11 +792,17 @@
week : function (mom) {
return weekOfYear(mom, this._week.dow, this._week.doy).week;
},
+
_week : {
dow : 0, // Sunday is the first day of the week.
doy : 6 // The week that contains Jan 1st is the first week of the year.
+ },
+
+ _invalidDate: 'Invalid date',
+ invalidDate: function () {
+ return this._invalidDate;
}
- };
+ });
// Loads a language definition into the `languages` cache. The function
// takes a key and optionally values. If not in the browser and no values
@@ -556,6 +817,11 @@
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
@@ -563,20 +829,52 @@
// 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 (!languages[key] && hasModule) {
- try {
- require('./lang/' + key);
- } catch (e) {
- // call with no params to set to default
- return moment.fn._lang;
+
+ if (!isArray(key)) {
+ //short-circuit everything else
+ lang = get(key);
+ if (lang) {
+ return lang;
}
+ key = [key];
}
- return languages[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
@@ -584,7 +882,7 @@
function removeFormattingTokens(input) {
- if (input.match(/\[.*\]/)) {
+ if (input.match(/\[[\s\S]/)) {
return input.replace(/^\[|\]$/g, "");
}
return input.replace(/\\/g, "");
@@ -612,15 +910,12 @@
// format date using native date object
function formatMoment(m, format) {
- var i = 5;
- function replaceLongDateFormatTokens(input) {
- return m.lang().longDateFormat(input) || input;
+ if (!m.isValid()) {
+ return m.lang().invalidDate();
}
- while (i-- && localFormattingTokens.test(format)) {
- format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
- }
+ format = expandFormat(format, m.lang());
if (!formatFunctions[format]) {
formatFunctions[format] = makeFormatFunction(format);
@@ -629,6 +924,23 @@
return formatFunctions[format](m);
}
+ function expandFormat(format, lang) {
+ var i = 5;
+
+ function replaceLongDateFormatTokens(input) {
+ return lang.longDateFormat(input) || input;
+ }
+
+ localFormattingTokens.lastIndex = 0;
+ while (i >= 0 && localFormattingTokens.test(format)) {
+ format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
+ localFormattingTokens.lastIndex = 0;
+ i -= 1;
+ }
+
+ return format;
+ }
+
/************************************
Parsing
@@ -637,16 +949,32 @@
// get the regex to find the next token
function getParseRegexForToken(token, config) {
+ var a, strict = config._strict;
switch (token) {
case 'DDDD':
return parseTokenThreeDigits;
case 'YYYY':
- return parseTokenFourDigits;
+ case 'GGGG':
+ case 'gggg':
+ return strict ? parseTokenFourDigits : parseTokenOneToFourDigits;
+ case 'Y':
+ case 'G':
+ case 'g':
+ return parseTokenSignedNumber;
+ case 'YYYYYY':
case 'YYYYY':
- return parseTokenSixDigits;
+ case 'GGGGG':
+ case 'ggggg':
+ return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
case 'S':
+ if (strict) { return parseTokenOneDigit; }
+ /* falls through */
case 'SS':
+ if (strict) { return parseTokenTwoDigits; }
+ /* falls through */
case 'SSS':
+ if (strict) { return parseTokenThreeDigits; }
+ /* falls through */
case 'DDD':
return parseTokenOneToThreeDigits;
case 'MMM':
@@ -665,13 +993,20 @@
return parseTokenTimezone;
case 'T':
return parseTokenT;
+ case 'SSSS':
+ return parseTokenDigits;
case 'MM':
case 'DD':
case 'YY':
+ case 'GG':
+ case 'gg':
case 'HH':
case 'hh':
case 'mm':
case 'ss':
+ case 'ww':
+ case 'WW':
+ return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits;
case 'M':
case 'D':
case 'd':
@@ -679,16 +1014,23 @@
case 'h':
case 'm':
case 's':
+ case 'w':
+ case 'W':
+ case 'e':
+ case 'E':
return parseTokenOneOrTwoDigits;
default :
- return new RegExp(token.replace('\\', ''));
+ a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i"));
+ return a;
}
}
function timezoneMinutesFromString(string) {
- var tzchunk = (parseTokenTimezone.exec(string) || [])[0],
- parts = (tzchunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
- minutes = +(parts[1] * 60) + ~~parts[2];
+ string = string || "";
+ var possibleTzMatches = (string.match(parseTokenTimezone) || []),
+ tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
+ parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
+ minutes = +(parts[1] * 60) + toInt(parts[2]);
return parts[0] === '+' ? -minutes : minutes;
}
@@ -701,34 +1043,43 @@
// MONTH
case 'M' : // fall through to MM
case 'MM' :
- datePartArray[1] = (input == null) ? 0 : ~~input - 1;
+ if (input != null) {
+ datePartArray[MONTH] = toInt(input) - 1;
+ }
break;
case 'MMM' : // fall through to MMMM
case 'MMMM' :
a = getLangDefinition(config._l).monthsParse(input);
// if we didn't find a month name, mark the date as invalid.
if (a != null) {
- datePartArray[1] = a;
+ datePartArray[MONTH] = a;
} else {
- config._isValid = false;
+ config._pf.invalidMonth = input;
}
break;
// DAY OF MONTH
- case 'D' : // fall through to DDDD
- case 'DD' : // fall through to DDDD
+ case 'D' : // fall through to DD
+ case 'DD' :
+ if (input != null) {
+ datePartArray[DATE] = toInt(input);
+ }
+ break;
+ // DAY OF YEAR
case 'DDD' : // fall through to DDDD
case 'DDDD' :
if (input != null) {
- datePartArray[2] = ~~input;
+ config._dayOfYear = toInt(input);
}
+
break;
// YEAR
case 'YY' :
- datePartArray[0] = ~~input + (~~input > 68 ? 1900 : 2000);
+ datePartArray[YEAR] = toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
break;
case 'YYYY' :
case 'YYYYY' :
- datePartArray[0] = ~~input;
+ case 'YYYYYY' :
+ datePartArray[YEAR] = toInt(input);
break;
// AM / PM
case 'a' : // fall through to A
@@ -740,23 +1091,24 @@
case 'HH' : // fall through to hh
case 'h' : // fall through to hh
case 'hh' :
- datePartArray[3] = ~~input;
+ datePartArray[HOUR] = toInt(input);
break;
// MINUTE
case 'm' : // fall through to mm
case 'mm' :
- datePartArray[4] = ~~input;
+ datePartArray[MINUTE] = toInt(input);
break;
// SECOND
case 's' : // fall through to ss
case 'ss' :
- datePartArray[5] = ~~input;
+ datePartArray[SECOND] = toInt(input);
break;
// MILLISECOND
case 'S' :
case 'SS' :
case 'SSS' :
- datePartArray[6] = ~~ (('0.' + input) * 1000);
+ case 'SSSS' :
+ datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000);
break;
// UNIX TIMESTAMP WITH MS
case 'X':
@@ -768,11 +1120,29 @@
config._useUTC = true;
config._tzm = timezoneMinutesFromString(input);
break;
- }
-
- // if the input is null, the date is not valid
- if (input == null) {
- config._isValid = false;
+ 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;
+ }
+ break;
}
}
@@ -780,124 +1150,257 @@
// the array should mirror the parameters below
// note: all values past the year are optional and will default to the lowest possible value.
// [year, month, day , hour, minute, second, millisecond]
- function dateFromArray(config) {
- var i, date, input = [];
+ function dateFromConfig(config) {
+ var i, date, input = [], currentDate,
+ yearToUse, fixYear, w, temp, lang, weekday, week;
if (config._d) {
return;
}
- for (i = 0; i < 7; i++) {
+ currentDate = currentDateArray(config);
+
+ //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] =