From: Tim Wood Date: Thu, 1 Dec 2011 01:23:23 +0000 (-0800) Subject: Adding timezone parsing and formatting #75 X-Git-Tag: 1.2.0~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=de8b7c5827d2b852a79b2fcebeaf1c29e435f64d;p=thirdparty%2Fmoment.git Adding timezone parsing and formatting #75 --- diff --git a/moment.js b/moment.js index 15c700db8..9ff4059ce 100644 --- a/moment.js +++ b/moment.js @@ -76,7 +76,8 @@ 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, @@ -173,6 +174,10 @@ // 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' : @@ -189,9 +194,13 @@ // 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, @@ -199,6 +208,7 @@ // function to convert string input to date function addTime(format, input) { + var a; switch (format) { // MONTH case 'M' : @@ -222,7 +232,7 @@ inArray[0] = input + (input > 70 ? 1900 : 2000); break; case 'YYYY' : - inArray[0] = ~~input; + inArray[0] = ~~Math.abs(input); break; // AM / PM case 'a' : @@ -252,6 +262,24 @@ 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++) { @@ -265,7 +293,11 @@ 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 @@ -285,7 +317,7 @@ // 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, @@ -440,6 +472,10 @@ return this._d; }, + toString : function () { + return this._d.toString(); + }, + format : function (inputString) { return formatDate(this._d, inputString); }, diff --git a/sitesrc/js/unit-tests.js b/sitesrc/js/unit-tests.js index 9e7e252a0..f1a4244bb 100755 --- a/sitesrc/js/unit-tests.js +++ b/sitesrc/js/unit-tests.js @@ -84,6 +84,27 @@ test("string with format", 17, function() { } }); +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'); @@ -320,16 +341,18 @@ test("format YY", 1, function() { 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'); });