-
Notifications
You must be signed in to change notification settings - Fork 22.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Firefox mangles date axis (possibly only during BST?) #1196
Comments
I am not able to reproduce this problem in Firefox, either in the current version (20) or in ancient 3.6. It would be helpful if you could isolate where the problem is occurring. For example, is x.ticks returning the wrong values (i.e., not in midnight local time)? Or is it a problem with how the dates are formatted? Since I cannot reproduce the problem, I cannot investigate further. Also, you are using an ancient version of D3. You want something like: <script charset="utf-8" src="http://d3js.org/d3.v3.min.js"></script> And you are parsing dates using the Date constructor, rather than d3.time.format, and this behavior varies from browser to browser and should not be relied on. |
On further investigation getUTCHours() seems to have inconsistent behaviour Current (BST)
Historical (GMT/UTC)
Recent (BST)
I changed the fiddle when I was running it to pick up the latest D3 This may not be your problem after all but is there a way I can override the use of getUTCHours() ? |
The nature of British Summer Time (or daylight saving time) is that it is only active part of the year. Therefore it is entirely expected that, depending on the date of the year, the offset between getHours and getUTCHours will change. For example, I am in Pacific Daylight Time, PDT, so my offset from UTC is -7 hours (-420 minutes):
However, on November 3, we’ll switch back to Pacific Standard Time, PST, changing the offset:
|
OK but I'm only specifying a date in the data (and assuming zero time). function d3_time_scaleFormat(formats) { var d3_time_scaleUTCFormats = [ [ d3.time.format.utc("%Y"), function(d) { |
Yes, but since your date is specified in local time, it will be either in BST or GMT depending on the date. The code that you’ve pasted in applies to d3.time.scale.utc, the UTC time scale, not d3.time.scale, the local time scale. |
Sorry, I pasted the wrong bit in. It IS selecting the time format in the local scale. The point is this only happens in Firefox. What can I do to get around it? |
Again, I don't understand the problem, and I can't reproduce it. What you’ve shown me with getHours vs. getUTCHours is entirely expected. I can only offer clarification on information you provide, as the example JsFiddle does not exhibit the described behavior in any browser I can test on. I would, however, recommend you fix your code to use d3.time.format to parse dates, rather than relying on the Date constructor. |
Sorry it's late and I've got myself tied up in knots - ignore getUTCHours. With the latest d3 and firefox in the UK today and data including dates such as "09/22/11", firefox returns 1 for .getHours() in d3_time_scaleLocalFormats, causing d3_time_scaleFormat to display the x axis as "01 AM" rather than "25 Sep". The fiddle isn't mine so I'm not entirely able to follow what it's doing but if I do (new Date("09/22/11")).getHours() in the firebug console I get 0 as I'd expect, It's only once the data is inside d3_time_scaleLocalFormats that it returns 1 on Firefox for some reason. |
I would avoid using (There may still be a bug in D3 relating to years prior to 1970.) |
Possible fix for the <1970 dates (which have negative timestamps): diff --git a/src/time/day.js b/src/time/day.js
index cd004a8..4d3f5c5 100644
--- a/src/time/day.js
+++ b/src/time/day.js
@@ -5,6 +5,7 @@ import "year";
d3.time.day = d3_time_interval(function(date) {
var day = new d3_time(1970, 0);
day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
+ day.setHours(0, 0, 0, 0);
return day;
}, function(date, offset) {
date.setDate(date.getDate() + offset); |
I've changed all the dates to use 2011 and replaced getDate() with function getDate(d) { And still get "01 AM" all along the x axis Is that not what you meant by date parsing? |
Is the 1 AM business something to do with interpolation for the tick marks? |
d3.time.day should always return midnights. However, Firefox doesn't return midnight for the following: var d = new Date(1970, 0); d.setFullYear(2011, 8, 22); // Thu Sep 22 2011 01:00:00 GMT+0100 (BST) Chrome (and Node.js) both return: // Thu Sep 22 2011 00:00:00 GMT+0100 (BST) This is because `new Date(1970, 0)` has different daylight saving behaviour in the two browsers. Chrome: Thu Jan 01 1970 00:00:00 GMT+0000 (GMT) Firefox: Thu Jan 01 1970 01:00:00 GMT+0100 (BST) In fact, Firefox is more correct! The UK was on permanent BST from February 1968 until October 1971. This seemingly minor difference in interpretation results in non-midnight times being returned for all day intervals and other intervals that use d3.time.day internally. The fix forces midnight to always be returned. Fixes #1196.
d3.time.day should always return midnights. However, Firefox doesn't return midnight for the following: var d = new Date(1970, 0); d.setFullYear(2011, 8, 22); // Thu Sep 22 2011 01:00:00 GMT+0100 (BST) Chrome and Node.js return: // Thu Sep 22 2011 00:00:00 GMT+0100 (BST) This is because `new Date(1970, 0)` has different daylight saving behaviour in the two browsers. Chrome: Thu Jan 01 1970 00:00:00 GMT+0000 (GMT) Firefox: Thu Jan 01 1970 01:00:00 GMT+0100 (BST) In fact, Firefox is more correct! The UK was on permanent BST from February 1968 until October 1971. This seemingly minor difference in interpretation results in non-midnight times being returned for all day intervals and other intervals that use d3.time.day internally. The fix forces midnight to always be returned. Fixes #1196.
This really is a bug relating to the UK being on permanent BST during 1970. Firefox was returning 1AM (BST) for the epoch, whereas Chrome was returning midnight (GMT). |
That patch is exactly what I want - works in Firefox (Win &, Linux and Android JB) and doesn't break on IE9 or Chrome. Good work! |
While note as complete a solution as #1197, this fixes the immediate problem of d3.time.day not returning midnights when on British Summer Time (BST), due to the UK being on permanent BST during 1970.
Fix merged into #1285 for 3.2. |
Example from an old stackoverflow question:
http://jsfiddle.net/nrabinowitz/JTrnC/
In firefox the date axis is filled with "01 AM" markers instead of the dates visible in Chrome and IE.
Stepping through, it looks like Firefox is translating dates with no time as occuring at 1AM, leading d3_time_scaleFormat() to select the format that returns getUTCHours() rather than the day and date.
Would it be better to use getHours() as the user is probably more interested in local times (I know I'm opening a can of worms here)?
BST is UTC+1, by the way, what we laugingly refer to in the UK as British "Summer" Time.
The text was updated successfully, but these errors were encountered: