Skip to content

Commit

Permalink
Fix a daylight savings bug in d3.time.format.
Browse files Browse the repository at this point in the history
We weren't computing the day-of-year number correctly, which affected both day
number and week number directives (%j, %U, and %W).
  • Loading branch information
mbostock committed Oct 12, 2011
1 parent 846bd5c commit c86108e
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 19 deletions.
2 changes: 1 addition & 1 deletion d3.js
Expand Up @@ -10,7 +10,7 @@ try {
d3_style_setProperty.call(this, name, value + "", priority);
};
}
d3 = {version: "2.4.2"}; // semver
d3 = {version: "2.4.3"}; // semver
var d3_array = d3_arraySlice; // conversion for NodeLists

function d3_arrayCopy(pseudoarray) {
Expand Down
2 changes: 1 addition & 1 deletion d3.min.js

Large diffs are not rendered by default.

21 changes: 15 additions & 6 deletions d3.time.js
Expand Up @@ -302,18 +302,22 @@ function d3_time_year(d) {
return new d3_time(d.getFullYear(), 0, 1);
}

function d3_time_daysElapsed(d0, d1) {
return ~~((d1 - d0) / 864e5 - (d1.getTimezoneOffset() - d0.getTimezoneOffset()) / 1440);
}

function d3_time_dayOfYear(d) {
return d3_time_zfill3(1 + ~~((d - d3_time_year(d)) / 864e5));
return d3_time_zfill3(1 + d3_time_daysElapsed(d3_time_year(d), d));
}

function d3_time_weekNumberSunday(d) {
var d0 = d3_time_year(d);
return d3_time_zfill2(~~(((d - d0) / 864e5 + d0.getDay()) / 7));
return d3_time_zfill2(~~((d3_time_daysElapsed(d0, d) + d0.getDay()) / 7));
}

function d3_time_weekNumberMonday(d) {
var d0 = d3_time_year(d);
return d3_time_zfill2(~~(((d - d0) / 864e5 + (d0.getDay() + 6) % 7) / 7));
return d3_time_zfill2(~~((d3_time_daysElapsed(d0, d) + (d0.getDay() + 6) % 7) / 7));
}

// TODO table of time zone offset names?
Expand All @@ -328,9 +332,14 @@ d3.time.format.utc = function(template) {
var local = d3.time.format(template);

function format(date) {
var utc = new d3_time_format_utc();
utc._ = date;
return local(utc);
try {
d3_time = d3_time_format_utc;
var utc = new d3_time();
utc._ = date;
return local(utc);
} finally {
d3_time = Date;
}
}

format.parse = function(string) {
Expand Down
2 changes: 1 addition & 1 deletion d3.time.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "d3",
"version": "2.4.2",
"version": "2.4.3",
"description": "A small, free JavaScript library for manipulating documents based on data.",
"keywords": [
"dom",
Expand Down
2 changes: 1 addition & 1 deletion src/core/core.js
@@ -1 +1 @@
d3 = {version: "2.4.2"}; // semver
d3 = {version: "2.4.3"}; // semver
11 changes: 8 additions & 3 deletions src/time/format-utc.js
Expand Up @@ -2,9 +2,14 @@ d3.time.format.utc = function(template) {
var local = d3.time.format(template);

function format(date) {
var utc = new d3_time_format_utc();
utc._ = date;
return local(utc);
try {
d3_time = d3_time_format_utc;
var utc = new d3_time();
utc._ = date;
return local(utc);
} finally {
d3_time = Date;
}
}

format.parse = function(string) {
Expand Down
10 changes: 7 additions & 3 deletions src/time/format.js
Expand Up @@ -299,18 +299,22 @@ function d3_time_year(d) {
return new d3_time(d.getFullYear(), 0, 1);
}

function d3_time_daysElapsed(d0, d1) {
return ~~((d1 - d0) / 864e5 - (d1.getTimezoneOffset() - d0.getTimezoneOffset()) / 1440);
}

function d3_time_dayOfYear(d) {
return d3_time_zfill3(1 + ~~((d - d3_time_year(d)) / 864e5));
return d3_time_zfill3(1 + d3_time_daysElapsed(d3_time_year(d), d));
}

function d3_time_weekNumberSunday(d) {
var d0 = d3_time_year(d);
return d3_time_zfill2(~~(((d - d0) / 864e5 + d0.getDay()) / 7));
return d3_time_zfill2(~~((d3_time_daysElapsed(d0, d) + d0.getDay()) / 7));
}

function d3_time_weekNumberMonday(d) {
var d0 = d3_time_year(d);
return d3_time_zfill2(~~(((d - d0) / 864e5 + (d0.getDay() + 6) % 7) / 7));
return d3_time_zfill2(~~((d3_time_daysElapsed(d0, d) + (d0.getDay() + 6) % 7) / 7));
}

// TODO table of time zone offset names?
Expand Down
28 changes: 26 additions & 2 deletions test/time/format-test.js
Expand Up @@ -72,7 +72,13 @@ suite.addBatch({
"formats zero-padded day of year": function(format) {
var f = format("%j");
assert.equal(f(local(1990, 0, 1)), "001");
assert.equal(f(local(1990, 5, 1)), "151");
assert.equal(f(local(1990, 5, 1)), "152");
assert.equal(f(local(2010, 2, 13)), "072");
assert.equal(f(local(2010, 2, 14)), "073"); // DST begins
assert.equal(f(local(2010, 2, 15)), "074");
assert.equal(f(local(2010, 10, 6)), "310");
assert.equal(f(local(2010, 10, 7)), "311"); // DST ends
assert.equal(f(local(2010, 10, 8)), "312");
},
"formats zero-padded month": function(format) {
var f = format("%m");
Expand Down Expand Up @@ -103,6 +109,12 @@ suite.addBatch({
var f = format("%U");
assert.equal(f(local(1990, 0, 1)), "00");
assert.equal(f(local(1990, 5, 1)), "21");
assert.equal(f(local(2010, 2, 13, 23)), "10");
assert.equal(f(local(2010, 2, 14, 00)), "11"); // DST begins
assert.equal(f(local(2010, 2, 15, 00)), "11");
assert.equal(f(local(2010, 10, 6, 23)), "44");
assert.equal(f(local(2010, 10, 7, 00)), "45"); // DST ends
assert.equal(f(local(2010, 10, 8, 00)), "45");
},
"formats locale date": function(format) {
var f = format("%x");
Expand Down Expand Up @@ -198,7 +210,13 @@ suite.addBatch({
"formats zero-padded day of year": function(format) {
var f = format("%j");
assert.equal(f(utc(1990, 0, 1)), "001");
assert.equal(f(utc(1990, 5, 1)), "151");
assert.equal(f(utc(1990, 5, 1)), "152");
assert.equal(f(utc(2010, 2, 13, 23)), "072");
assert.equal(f(utc(2010, 2, 14, 00)), "073"); // DST begins
assert.equal(f(utc(2010, 2, 15, 00)), "074");
assert.equal(f(utc(2010, 10, 6, 23)), "310");
assert.equal(f(utc(2010, 10, 7, 00)), "311"); // DST ends
assert.equal(f(utc(2010, 10, 8, 00)), "312");
},
"formats zero-padded month": function(format) {
var f = format("%m");
Expand Down Expand Up @@ -229,6 +247,12 @@ suite.addBatch({
var f = format("%U");
assert.equal(f(utc(1990, 0, 1)), "00");
assert.equal(f(utc(1990, 5, 1)), "21");
assert.equal(f(utc(2010, 2, 13, 23)), "10");
assert.equal(f(utc(2010, 2, 14, 00)), "11"); // DST begins
assert.equal(f(utc(2010, 2, 15, 00)), "11");
assert.equal(f(utc(2010, 10, 6, 23)), "44");
assert.equal(f(utc(2010, 10, 7, 00)), "45"); // DST ends
assert.equal(f(utc(2010, 10, 8, 00)), "45");
},
"formats locale date": function(format) {
var f = format("%x");
Expand Down

0 comments on commit c86108e

Please sign in to comment.