I'm trying to use d3.time.scale.utc()
to generate a time scale that is the same on any device, as mentioned in the docs.
However, both of the following scales seem to generate tick dates that are locally formatted - in my case the returned dates are using BST and GMT:
var start = new Date("Mon Oct 21 2013 00:00:00 GMT+0000 (BST)");
var end = new Date("Mon Dec 02 2013 00:00:00 GMT+0000 (GMT)")
var x = d3.time.scale.utc()
.domain([start, end])
.range([0, 800])
.ticks(d3.time.mondays, 1);
console.log(x);
var y = d3.time.scale()
.domain([start, end])
.range([0, 800])
.ticks(d3.time.mondays, 1);
console.log(y);
How can I ask D3 to generate me tick dates that are not set to a local timezone?
Fiddle here: http://jsfiddle.net/qE9ur/
The problem is simply that you are logging date objects to the console, and your browser is applying default formatting to those objects to convert them to your local time zone.
Using d3.time.scale.utc()
doesn't change the date objects. Javascript date objects are always stored internally as numbers of milliseconds since 1970.
What is unique about the UTC scale is the tickFormat
function, which uses a UTC time formatter by default. However, the tick format function doesn't affect logging to console, only when you're actually drawing the ticks as labels!
The following fiddle actually uses the tick formatting function of each scale to format the date objects logged to the console:
http://jsfiddle.net/qE9ur/1/
var start = new Date("Mon Oct 21 2013 00:00:00 GMT+0100 (BST)");
var end = new Date("Mon Dec 02 2013 00:00:00 GMT+0000 (GMT)")
var xScale = d3.time.scale.utc()
.domain([start, end])
.range([0, 800]);
var xTicks = xScale.ticks(d3.time.mondays, 1);
console.log( xTicks.map( xScale.tickFormat() ) );
var yScale = d3.time.scale()
.domain([start, end])
.range([0, 800]);
var yTicks = yScale.ticks(d3.time.mondays, 1);
console.log(yTicks.map( yScale.tickFormat() ) );
However, you'll discover another problem (assuming you're not in a GMT timezone). The default formatting function for a time scale is a multi-format: if values aren't for midnight, it will return the time instead of the date. When you specify the ticks as mondays
, it still calculates them as midnight monday in your current timezone, which for me is 6 or 7 hours off of UTC.
That's why there are UTC versions of all the time interval functions, as well. Changing the ticks specification to
var xTicks = xScale.ticks(d3.time.mondays.utc, 1);
gets the tick values to fall at midnight UTC: http://jsfiddle.net/qE9ur/2/
All that said, you'll still probably want to specify a custom tick formatter. The day of the week + day of the month format doesn't really work when you're scanning through multiple months on Mondays only.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With