m : 'minute',
h : 'hour',
d : 'day',
+ D : 'date',
w : 'week',
- W : 'isoweek',
+ 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
// Moment prototype object
function Moment(config) {
extend(this, config);
+
+ if (this._w) {
+ applyWeekData(this);
+ }
}
// Duration Constructor
}
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) {
return value;
}
+ function applyWeekData(m) {
+ var apply = function () {
+ var i, unit, norm, val, found = false;
+ for (i in arguments) {
+ unit = arguments[i];
+ norm = normalizeUnits(unit);
+ if (m._w[unit]) {
+ found = true;
+ val = m._w[unit];
+ val = i === '0' && val.length < 3 ? (parseInt(val, 10) > 68 ? '19' + val : '20' + val) : val;
+ m.set(norm, val);
+ }
+ else if (found) {
+ m.set(norm, unit === 'e' ? 0 : 1);
+ }
+ }
+ };
+
+ apply('gg', 'w', 'e');
+ apply('GG', 'W', 'E');
+
+ if (m._w['d']) {
+ m.day(m._w['d']);
+ }
+ }
+
/************************************
Languages
************************************/
case 'DDDD':
return parseTokenThreeDigits;
case 'YYYY':
+ case 'GGGG':
+ case 'gggg':
return parseTokenFourDigits;
case 'YYYYY':
+ case 'GGGGG':
+ case 'ggggg':
return parseTokenSixDigits;
case 'S':
case 'SS':
case 'MM':
case 'DD':
case 'YY':
+ case 'GG':
+ case 'gg':
case 'HH':
case 'hh':
case 'mm':
case 'h':
case 'm':
case 's':
+ case 'w':
+ case 'ww':
+ case 'W':
+ case 'WW':
+ case 'e':
+ case 'ee':
+ case 'E':
+ case 'EE':
return parseTokenOneOrTwoDigits;
default :
return new RegExp(regexpEscape(token.replace('\\', '')));
config._useUTC = true;
config._tzm = timezoneMinutesFromString(input);
break;
+ 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;
}
// if the input is null, the date is not valid
// date from string and format string
function makeDateFromStringAndFormat(config) {
+
if (config._strict) {
makeDateFromStringAndStrictFormat(config);
return;
}
+
// This array is used to make a Date, either with `new Date` or `Date.UTC`
var lang = getLangDefinition(config._l),
string = '' + config._i,
config._i = input = getLangDefinition().preparse(input);
}
+
if (moment.isMoment(input)) {
config = extend({}, input);
+
+ //null this out to prevent infinite loops
+ config._w = null;
+
config._d = new Date(+input._d);
} else if (format) {
if (isArray(format)) {
var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
if (input != null) {
if (typeof input === 'string') {
- input = this.lang().weekdaysParse(input);
- if (typeof input !== 'number') {
- return this;
+ if (!isNaN(input)) {
+ input = parseInt(input, 10);
+ }
+ else {
+ input = this.lang().weekdaysParse(input);
+ if (typeof input !== 'number') {
+ return this;
+ }
}
}
return this.add({ d : input - day });
this.date(1);
/* falls through */
case 'week':
- case 'isoweek':
+ case 'isoWeek':
case 'day':
this.hours(0);
/* falls through */
// weeks are a special case
if (units === 'week') {
this.weekday(0);
- } else if (units === 'isoweek') {
+ } else if (units === 'isoWeek') {
this.isoWeekday(1);
}
endOf: function (units) {
units = normalizeUnits(units);
- return this.startOf(units).add((units === 'isoweek' ? 'week' : units), 1).subtract('ms', 1);
+ return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1);
},
isAfter: function (input, units) {
get : function (units) {
units = normalizeUnits(units);
- return this[units.toLowerCase()]();
+ return this[units]();
},
set : function (units, value) {
units = normalizeUnits(units);
- this[units.toLowerCase()](value);
+ if (typeof this[units] === 'function') {
+ this[units](value);
+ }
return this;
},
test.equal(moment('2012 july', 'YYYY MMM', 'en').month(), 6, "should be able to parse in a specific language");
moment.lang('parselang', null);
+ test.done();
+ },
+
+ "parsing week and weekday information" : function (test) {
+
+ //year
+ test.equal(moment('99', 'gg').format('YYYY MM DD'), "1998 12 27", 'week-year two digits');
+ test.equal(moment('1999', 'gggg').format('YYYY MM DD'), "1998 12 27", 'week-year four digits');
+ test.equal(moment('99', 'GG').format('YYYY MM DD'), "1999 01 04", 'iso week-year two digits');
+ test.equal(moment('1999', 'GGGG').format('YYYY MM DD'), "1999 01 04", 'iso week-year four digits');
+
+ //year + week
+ test.equal(moment('1999 37', 'gggg w').format('YYYY MM DD'), "1999 09 05", 'week');
+ test.equal(moment('1999 37', 'gggg ww').format('YYYY MM DD'), "1999 09 05", 'week double');
+ test.equal(moment('1999 37', 'GGGG W').format('YYYY MM DD'), "1999 09 13", 'iso week');
+ test.equal(moment('1999 37', 'GGGG WW').format('YYYY MM DD'), "1999 09 13", 'iso week double');
+
+ //year + week + day
+ test.equal(moment('1999 37 4', 'gggg ww e').format('YYYY MM DD'), "1999 09 09", 'day');
+ test.equal(moment('1999 37 4', 'gggg ww ee').format('YYYY MM DD'), "1999 09 09", 'day double');
+ test.equal(moment('1999 37 4', 'GGGG WW E').format('YYYY MM DD'), "1999 09 16", 'iso day');
+ test.equal(moment('1999 37 4', 'GGGG WW EE').format('YYYY MM DD'), "1999 09 16", 'iso day double');
+
+ //d
+ test.equal(moment('1999 37 4', 'gggg ww d').format('YYYY MM DD'), "1999 09 09", 'd');
+ test.equal(moment('1999 37 Th', 'gggg ww dd').format('YYYY MM DD'), "1999 09 09", 'dd');
+ test.equal(moment('1999 37 Thu', 'gggg ww ddd').format('YYYY MM DD'), "1999 09 09", 'ddd');
+ test.equal(moment('1999 37 Thursday', 'gggg ww dddd').format('YYYY MM DD'), "1999 09 09", 'dddd');
+
+ //lower-order only
+ test.equal(moment('22', 'ww').week(), 22, "week sets the week by itself");
+ test.equal(moment('22', 'ww').year(), moment().year(), "week keeps this year");
+ test.equal(moment('2013 22', 'YYYY ww').year(), 2013, "week keeps parsed year");
+
+ test.equal(moment('22', 'WW').isoWeek(), 22, "iso week sets the week by itself");
+ test.equal(moment('2013 22', 'YYYY WW').year(), 2013, "iso week keeps parsed year");
+ test.equal(moment('22', 'WW').year(), moment().year(), "iso week keeps this year");
+
+ test.equal(moment('3', 'ee').weekday(), 3, "day sets the day by itself");
+ test.equal(moment('2013 07 03', 'YYYY MM ee').month(), 6, "weekday keeps the parsed year and month");
+
+ test.equal(moment('3', 'EE').isoWeekday(), 3, "iso day sets the day by itself");
+ test.equal(moment('2013 07 03', 'YYYY MM EE').month(), 6, "iso weekday keeps the parsed year and month");
+
+ //order
+ test.equal(moment('6 2013 2', 'e gggg w').format('YYYY MM DD'), "2013 01 12", "order doesn't matter");
+ test.equal(moment('6 2013 2', 'E GGGG W').format('YYYY MM DD'), "2013 01 12", "iso order doesn't matter");
+
test.done();
}
};
},
"getters programmatic" : function (test) {
- test.expect(8);
-
var a = moment([2011, 9, 12, 6, 7, 8, 9]);
test.equal(a.get('year'), 2011, 'year');
test.equal(a.get('month'), 9, 'month');
test.equal(a.get('minute'), 7, 'minute');
test.equal(a.get('second'), 8, 'second');
test.equal(a.get('milliseconds'), 9, 'milliseconds');
+
+ //actual getters tested elsewhere
+ test.equal(a.get('weekday'), a.weekday(), 'weekday');
+ test.equal(a.get('isoWeekday'), a.isoWeekday(), 'isoWeekday');
+ test.equal(a.get('week'), a.week(), 'week');
+ test.equal(a.get('isoWeek'), a.isoWeek(), 'isoWeek');
+ test.equal(a.get('dayOfYear'), a.dayOfYear(), 'dayOfYear');
test.done();
},
},
"setter programmatic" : function (test) {
- test.expect(9);
-
var a = moment();
a.set('year', 2011);
a.set('month', 9);
test.done();
},
+ "setters programatic with weeks" : function (test) {
+ var a = moment();
+ a.set('weekYear', 2001);
+ a.set('week', 49);
+ a.set('day', 4);
+ test.equals(a.weekYear(), 2001);
+ test.equals(a.week(), 49);
+ test.equals(a.day(), 4);
+
+ a.set('weekday', 1);
+ test.equals(a.weekday(), 1);
+
+ test.done();
+ },
+
+ "setters programatic with weeks ISO" : function (test) {
+ var a = moment();
+ a.set('isoWeekYear', 2001);
+ a.set('isoWeek', 49);
+ a.set('isoWeekday', 4);
+
+ test.equals(a.weekYear(), 2001);
+ test.equals(a.week(), 49);
+ test.equals(a.day(), 4);
+
+ test.done();
+ },
+
"setters strings" : function (test) {
test.expect(7);
exports.normalizeUnits = {
"normalize units" : function (test) {
- test.expect(45);
- var fullKeys = ["year", "month", "isoweek", "week", "day", "hour", "minute", "second", "millisecond"],
- aliases = ["y", "M", "W", "w", "d", "h", "m", "s", "ms"],
+ var fullKeys = ["year", "month", "isoWeek", "week", "day", "hour", "minute", "second", "millisecond", "date", 'dayOfYear', 'weekday', 'isoWeekday', 'weekYear', 'isoWeekYear'],
+ aliases = ["y", "M", "W", "w", "d", "h", "m", "s", "ms", "D", 'DDD', 'e', 'E', 'gg', 'GG'],
length = fullKeys.length,
fullKey,
fullKeyCaps,
fullKeyPlural,
fullKeyCapsPlural,
+ fullKeyLower,
alias,
index;
for (index = 0; index < length; index += 1) {
fullKey = fullKeys[index];
fullKeyCaps = fullKey.toUpperCase();
+ fullKeyLower = fullKey.toLowerCase();
fullKeyPlural = fullKey + "s";
fullKeyCapsPlural = fullKeyCaps + "s";
alias = aliases[index];