Commit 7e2cf5ad authored by Jason Davies's avatar Jason Davies
Browse files

Support parsing timezone offsets.

Note that the resulting Date object can only be in the local timezone
(or UTC), due to the limitations of JavaScript Dates.

Fixes #1494.
parent fc5a5864
......@@ -8513,17 +8513,18 @@ d3 = function() {
H: 0,
M: 0,
S: 0,
L: 0
L: 0,
Z: null
}, i = d3_time_parse(d, template, string, 0);
if (i != string.length) return null;
if ("p" in d) d.H = d.H % 12 + d.p * 12;
var date = new d3_date();
var utcZone = d.Z != null && d3_date !== d3_date_utc, date = new (utcZone ? d3_date_utc : d3_date)();
if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) {
date.setFullYear(d.y, 0, 1);
date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7);
} else date.setFullYear(d.y, d.m, d.d);
date.setHours(d.H, d.M, d.S, d.L);
return date;
date.setHours(d.H + Math.floor(d.Z / 100), d.M + d.Z % 100, d.S, d.L);
return utcZone ? new d3_date(+date) : date;
};
format.toString = function() {
return template;
......@@ -8652,6 +8653,7 @@ d3 = function() {
X: d3_time_parseLocaleTime,
y: d3_time_parseYear,
Y: d3_time_parseFullYear,
Z: d3_time_parseZone,
"%": d3_time_parseLiteralPercent
};
function d3_time_parseWeekdayAbbrev(date, string, i) {
......@@ -8708,6 +8710,10 @@ d3 = function() {
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1;
}
function d3_time_parseZone(date, string, i) {
return /^[+-]\d{4}$/.test(string = string.substring(i, i + 5)) ? (date.Z = +string,
i + 5) : -1;
}
function d3_time_expandYear(d) {
return d + (d > 68 ? 1900 : 2e3);
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -31,14 +31,15 @@ function d3_time_format(template) {
}
format.parse = function(string) {
var d = {y: 1900, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0},
var d = {y: 1900, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0, Z: null},
i = d3_time_parse(d, template, string, 0);
if (i != string.length) return null;
// The am-pm flag is 0 for AM, and 1 for PM.
if ("p" in d) d.H = d.H % 12 + d.p * 12;
var date = new d3_date;
var utcZone = d.Z != null && d3_date !== d3_date_utc,
date = new (utcZone ? d3_date_utc : d3_date);
if ("j" in d) date.setFullYear(d.y, 0, d.j);
else if ("w" in d && ("W" in d || "U" in d)) {
date.setFullYear(d.y, 0, 1);
......@@ -46,8 +47,8 @@ function d3_time_format(template) {
? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7
: d.w + d.U * 7 - (date.getDay() + 6) % 7);
} else date.setFullYear(d.y, d.m, d.d);
date.setHours(d.H, d.M, d.S, d.L);
return date;
date.setHours(d.H + Math.floor(d.Z / 100), d.M + d.Z % 100, d.S, d.L);
return utcZone ? new d3_date(+date) : date;
};
format.toString = function() {
......@@ -161,7 +162,7 @@ var d3_time_parsers = {
X: d3_time_parseLocaleTime,
y: d3_time_parseYear,
Y: d3_time_parseFullYear,
// Z: function(d, s, i) { /*TODO time zone */ return i; },
Z: d3_time_parseZone,
"%": d3_time_parseLiteralPercent
};
......@@ -231,6 +232,12 @@ function d3_time_parseYear(date, string, i) {
return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1;
}
function d3_time_parseZone(date, string, i) {
return /^[+-]\d{4}$/.test(string = string.substring(i, i + 5))
? (date.Z = +string, i + 5)
: -1;
}
function d3_time_expandYear(d) {
return d + (d > 68 ? 1900 : 2000);
}
......
......@@ -284,6 +284,12 @@ suite.addBatch({
assert.deepEqual(p("% 02/03/1991"), local(1991, 1, 3));
assert.isNull(p("%% 03/10/2010"));
},
"parses timezone offset": function(format) {
var p = format("%m/%d/%Y %Z").parse;
assert.deepEqual(p("01/02/1990 +0000"), local(1990, 0, 1, 16));
assert.deepEqual(p("01/02/1990 +0100"), local(1990, 0, 1, 17));
assert.deepEqual(p("01/02/1990 -0100"), local(1990, 0, 1, 15));
},
"ignores optional padding modifier, skipping zeroes and spaces": function(format) {
var p = format("%-m/%0d/%_Y").parse;
assert.deepEqual(p("01/ 1/1990"), local(1990, 0, 1));
......
......@@ -211,6 +211,12 @@ suite.addBatch({
assert.deepEqual(p("12:00:00 pm"), utc(1900, 0, 1, 12, 0, 0));
assert.deepEqual(p("12:00:01 pm"), utc(1900, 0, 1, 12, 0, 1));
assert.deepEqual(p("11:59:59 PM"), utc(1900, 0, 1, 23, 59, 59));
},
"parses timezone offset": function(format) {
var p = format("%m/%d/%Y %Z").parse;
assert.deepEqual(p("01/02/1990 +0000"), utc(1990, 0, 2));
assert.deepEqual(p("01/02/1990 +0100"), utc(1990, 0, 2, 1));
assert.deepEqual(p("01/02/1990 -0100"), utc(1990, 0, 1, 23));
}
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment