currentHours = date.getHours(),
currentMinutes = date.getMinutes(),
currentSeconds = date.getSeconds(),
- charactersToReplace = /(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|zz?|LL?L?L?)/g,
+ currentZone = date.getTimezoneOffset(),
+ charactersToReplace = /(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|zz?|ZZ?|LL?L?L?)/g,
nonuppercaseLetters = /[^A-Z]/g,
timezoneRegex = /\([A-Za-z ]+\)|:[0-9]{2} [A-Z]{3} /g,
ordinal = moment.ordinal,
// depreciating 'zz' fall through to 'z'
case 'z' :
return (date.toString().match(timezoneRegex) || [''])[0].replace(nonuppercaseLetters, '');
+ case 'Z' :
+ return (currentZone > 0 ? '+' : '-') + leftZeroFill(~~(currentZone / 60), 2) + ':' + leftZeroFill(~~(currentZone % 60), 2);
+ case 'ZZ' :
+ return (currentZone > 0 ? '+' : '-') + leftZeroFill(~~(10 * currentZone / 6), 4);
// LONG DATES
case 'L' :
case 'LL' :
// date from string and format string
function makeDateFromStringAndFormat(string, format) {
- var inArray = [0],
- tokenCharacters = /(\\)?(MM?|DD?D?D?|YYYY|YY|a|A|hh?|HH?|mm?|ss?)/g,
- inputCharacters = /(\\)?([0-9]+|am|pm)/gi,
+ var inArray = [0, 0, 1, 0, 0, 0, 0],
+ timezoneHours = 0,
+ timezoneMinutes = 0,
+ isUsingUTC = false,
+ tokenCharacters = /(\\)?(MM?|DD?D?D?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|ZZ?)/g,
+ inputCharacters = /(\\)?([0-9]+|am|pm|([\+\-]\d\d:?\d\d))/gi,
+ timezoneParseRegex = /([\+\-]|\d\d)/gi,
inputParts = string.match(inputCharacters),
formatParts = format.match(tokenCharacters),
i,
// function to convert string input to date
function addTime(format, input) {
+ var a;
switch (format) {
// MONTH
case 'M' :
inArray[0] = input + (input > 70 ? 1900 : 2000);
break;
case 'YYYY' :
- inArray[0] = ~~input;
+ inArray[0] = ~~Math.abs(input);
break;
// AM / PM
case 'a' :
case 'ss' :
inArray[5] = ~~input;
break;
+ // TIMEZONE
+ case 'Z' :
+ // fall through to ZZ
+ case 'ZZ' :
+ isUsingUTC = true;
+ a = input.match(timezoneParseRegex);
+ if (a[1]) {
+ timezoneHours = ~~a[1];
+ }
+ if (a[2]) {
+ timezoneMinutes = ~~a[2];
+ }
+ // reverse offsets
+ if (a[0] === '-') {
+ timezoneHours = -timezoneHours;
+ timezoneMinutes = -timezoneMinutes;
+ }
+ break;
}
}
for (i = 0; i < formatParts.length; i++) {
if (! isPm && inArray[3] === 12) {
inArray[3] = 0;
}
- return dateFromArray(inArray);
+ // handle timezone
+ inArray[3] += timezoneHours;
+ inArray[4] += timezoneMinutes;
+ // return
+ return isUsingUTC ? new Date(Date.UTC.apply({}, inArray)) : dateFromArray(inArray);
}
// compare two arrays, return the number of differences
// date from string and array of format strings
function makeDateFromStringAndArray(string, formats) {
var output,
- inputCharacters = /(\\)?([0-9]+|am|pm)/gi,
+ inputCharacters = /(\\)?([0-9]+|am|pm|([\+\-]\d\d:?\d\d))/gi,
inputParts = string.match(inputCharacters),
scores = [],
scoreToBeat = 99,
return this._d;
},
+ toString : function () {
+ return this._d.toString();
+ },
+
format : function (inputString) {
return formatDate(this._d, inputString);
},
}
});
+test("string with format (timezone)", 8, function() {
+ equal(moment('5 +0700', 'H ZZ').native().getUTCHours(), 12, 'parse hours "5 +0700" ---> "H ZZ"');
+ equal(moment('5 +07:00', 'H Z').native().getUTCHours(), 12, 'parse hours "5 +07:00" ---> "H Z"');
+ equal(moment('5 +0730', 'H ZZ').native().getUTCMinutes(), 30, 'parse hours "5 +0730" ---> "H ZZ"');
+ equal(moment('5 +07:30', 'H Z').native().getUTCMinutes(), 30, 'parse hours "5 +07:30" ---> "H Z"');
+ equal(moment('5 -0100', 'H ZZ').native().getUTCHours(), 4, 'parse hours "5 -0100" ---> "H ZZ"');
+ equal(moment('5 -01:00', 'H Z').native().getUTCHours(), 4, 'parse hours "5 -01:00" ---> "H Z"');
+ equal(moment('5 -0130', 'H ZZ').native().getUTCMinutes(), 30, 'parse hours "5 -0130" ---> "H ZZ"');
+ equal(moment('5 -01:30', 'H Z').native().getUTCMinutes(), 30, 'parse hours "5 -01:30" ---> "H Z"');
+});
+
+test("string with format (timezone offset)", 3, function() {
+ var a = new Date(Date.UTC(2011, 0, 1, 1));
+ var b = moment('2011 1 1 0 +01:00', 'YYYY MM DD HH Z');
+ equal(a.getHours(), b.hours(), 'date created with utc == parsed string with timezone offset');
+ equal(+a, +b, 'date created with utc == parsed string with timezone offset');
+ var c = moment('2011 2 1 10 +05:00', 'YYYY MM DD HH Z');
+ var d = moment('2011 2 1 8 +07:00', 'YYYY MM DD HH Z');
+ equal(c.hours(), d.hours(), '10 am central time == 8 am pacific time');
+});
+
test("string with array of formats", 3, function() {
equal(moment('13-02-1999', ['MM-DD-YYYY', 'DD-MM-YYYY']).format('MM DD YYYY'), '02 13 1999', 'switching month and day');
equal(moment('02-13-1999', ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 13 1999', 'year last');
equal(b.format('YY'), '09', 'YY ---> 09');
});
-test("format timezone", 2, function() {
+test("format timezone", 4, function() {
var b = moment(new Date(2010, 1, 14, 15, 25, 50, 125));
ok(b.format('z').match(/^[A-Z]{3,5}$/), b.format('z') + ' ---> Something like "PST"');
ok(b.format('zz').match(/^[A-Z]{3,5}$/), b.format('zz') + ' ---> Something like "PST"');
+ ok(b.format('Z').match(/^[\+\-]\d\d:\d\d$/), b.format('Z') + ' ---> Something like "+07:30"');
+ ok(b.format('ZZ').match(/^[\+\-]\d{4}$/), b.format('ZZ') + ' ---> Something like "+0700"');
});
test("isDST", 2, function() {
// In the US 2011 March 13 is Daylight Savings Day
var a = moment(new Date(2011, 2, 12, 0, 0, 0)),
- b = moment(new Date(2011, 2, 14, 0, 0, 0));
+ b = moment(new Date(2011, 2, 14, 0, 0, 0));
ok(!a.isDST(), '2011 March 12 is not DST');
ok(b.isDST(), '2011 March 14 is DST');
});