Skip to content

Commit

Permalink
Merge pull request #4 from Mr0grog/parse-all-iso-tz-formats
Browse files Browse the repository at this point in the history
Modify time zone parsing (%Z) to accept any ISO 8601 compatible time zone format
  • Loading branch information
mbostock committed Oct 18, 2015
2 parents 2493e4a + 4fd3f10 commit 1e1a354
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Returns a new [*format* function](#_format) for the given string *specifier*. Th
* `%X` - the locale’s time, such as `%H:%M:%S`.*
* `%y` - year without century as a decimal number [00,99].
* `%Y` - year with century as a decimal number.
* `%Z` - time zone offset, such as `-0700`.
* `%Z` - time zone offset, such as `-0700`, `-07:00`, `-07`, or `Z`.
* `%%` - a literal percent sign (`%`).

Directives marked with an asterisk (*) may be affected by the [locale definition](#localeFormat). For `%U`, all days in a new year preceding the first Sunday are considered to be in week 0. For `%W`, all days in a new year preceding the first Monday are considered to be in week 0. Week numbers are computed using [*interval*.count](https://github.com/d3/d3-time#interval_count).
Expand Down
11 changes: 8 additions & 3 deletions src/locale.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,9 +357,14 @@ function parseYear(d, string, i) {
}

function parseZone(d, string, i) {
return /^[+-]\d{4}$/.test(string = string.slice(i, i + 5))
? (d.Z = -string, i + 5) // sign differs from getTimezoneOffset!
: -1;
var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6));
if (n) {
d.Z = n[1] ? 0 // 'Z' for UTC
: n[3] ? -(n[2] + n[3]) // sign differs from getTimezoneOffset!
: -n[2] * 100;
return i + n[0].length;
}
return -1;
}

function parseMonthNumber(d, string, i) {
Expand Down
20 changes: 20 additions & 0 deletions test/format-parse-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,26 @@ tape("format(\"%m/%d/%Y %Z\").parse(date) parses timezone offset", function(test
test.end();
});

tape("format(\"%m/%d/%Y %Z\").parse(date) parses timezone offset in the form '+-hh:mm'", function(test) {
var p = timeFormat.format("%m/%d/%Y %Z").parse;
test.deepEqual(p("01/02/1990 +01:30"), date.local(1990, 0, 1, 14, 30));
test.deepEqual(p("01/02/1990 -01:30"), date.local(1990, 0, 1, 17, 30));
test.end();
});

tape("format(\"%m/%d/%Y %Z\").parse(date) parses timezone offset in the form '+-hh'", function(test) {
var p = timeFormat.format("%m/%d/%Y %Z").parse;
test.deepEqual(p("01/02/1990 +01"), date.local(1990, 0, 1, 15));
test.deepEqual(p("01/02/1990 -01"), date.local(1990, 0, 1, 17));
test.end();
});

tape("format(\"%m/%d/%Y %Z\").parse(date) parses timezone offset in the form 'Z'", function(test) {
var p = timeFormat.format("%m/%d/%Y %Z").parse;
test.deepEqual(p("01/02/1990 Z"), date.local(1990, 0, 1, 16));
test.end();
});

tape("format(\"%-m/%0d/%_Y\").parse(date) ignores optional padding modifier, skipping zeroes and spaces", function(test) {
var p = timeFormat.format("%-m/%0d/%_Y").parse;
test.deepEqual(p("01/ 1/1990"), date.local(1990, 0, 1));
Expand Down
20 changes: 20 additions & 0 deletions test/utcFormat-parse-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,23 @@ tape("utcFormat(\"\").parse(date) parses timezone offset", function(test) {
test.deepEqual(p("01/02/1990 -0800"), date.local(1990, 0, 2));
test.end();
});

tape("utcFormat(\"\").parse(date) parses timezone offset (in the form '+-hh:mm')", function(test) {
var p = timeFormat.utcFormat("%m/%d/%Y %Z").parse;
test.deepEqual(p("01/02/1990 +01:30"), date.utc(1990, 0, 1, 22, 30));
test.deepEqual(p("01/02/1990 -01:30"), date.utc(1990, 0, 2, 1, 30));
test.end();
});

tape("utcFormat(\"\").parse(date) parses timezone offset (in the form '+-hh')", function(test) {
var p = timeFormat.utcFormat("%m/%d/%Y %Z").parse;
test.deepEqual(p("01/02/1990 +01"), date.utc(1990, 0, 1, 23));
test.deepEqual(p("01/02/1990 -01"), date.utc(1990, 0, 2, 1));
test.end();
});

tape("utcFormat(\"\").parse(date) parses timezone offset (in the form 'Z')", function(test) {
var p = timeFormat.utcFormat("%m/%d/%Y %Z").parse;
test.deepEqual(p("01/02/1990 Z"), date.utc(1990, 0, 2));
test.end();
});

0 comments on commit 1e1a354

Please sign in to comment.