D3.js:time.scale.utc()似乎对我没有任何作用?

时间:2014-02-11 19:15:13

标签: javascript d3.js

我正在尝试使用d3.time.scale.utc()生成与mentioned in the docs在任何设备上相同的时间刻度。

但是,以下两个比例似乎都会生成本地格式的刻度日期 - 在我的情况下,返回的日期使用的是BST和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);

如何让D3生成未设置为本地时区的刻度日期?

在这里小提琴:http://jsfiddle.net/qE9ur/

1 个答案:

答案 0 :(得分:11)

问题只是您将日期对象记录到控制台,而您的浏览器正在对这些对象应用默认格式以将它们转换为您当地的时区。

使用d3.time.scale.utc()不会更改日期对象。自1970年以来,Javascript日期对象始终在内部存储为毫秒数。

UTC比例的独特之处在于tickFormat功能,默认情况下使用UTC time formatter。但是,只有当您实际将标记作为标签绘制时,刻度格式功能才会影响到控制台的记录!

以下小提琴实际上使用每个音阶的刻度格式化功能来格式化记录到控制台的日期对象:
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() ) );

但是,你会发现另一个问题(假设你不在GMT时区)。时间刻度的默认格式化功能是多格式:如果值不是午夜,它将返回时间而不是日期。当您将刻度线指定为mondays时,它仍会将它们计算为您当前时区的午夜星期一,对我来说这是UTC的6或7小时。

这就是为什么所有时间间隔函数都有UTC版本的原因。将刻度线规格更改为

var xTicks =  xScale.ticks(d3.time.mondays.utc, 1);

获取滴答值在午夜UTC:http://jsfiddle.net/qE9ur/2/

所有这一切,你仍然可能想要指定一个自定义刻度格式化程序。当您在周一仅扫描多个月时,星期几+月份日期格式不起作用。