Chart.js: [Support] Set Timezone to UTC on Graph

Created on 6 Jun 2017  ·  11Comments  ·  Source: chartjs/Chart.js

Hi, I am trying to display the date on the x-axis to UTC, so everyone's graph has the same date. I followed the suggestions at https://stackoverflow.com/questions/40891462/chart-js-display-control-timescale-time-zone but I cannot get this to work. Here is my simple project https://jsfiddle.net/quantonos/znqfu2bp/ People should see 3am as the start time. I see 10pm EST since I'm in EST. Thanks

time scale enhancement

Most helpful comment

Using moment.utc gets me the correct time on the tooltip but the x-axis labels are still wrong.

xAxes: [ {type: 'time',time: { tooltipFormat: 'LT'}, ticks:{callback: function(value, index, values) {
          if (!values[index]) {return}
          return moment.utc(values[index]['value']).format('LT');
      }}}]

This gave me the format I want. No idea why the ticks formatting is independent of the tooltip formatting but this is a work around (ie recasting the original value back into a moment.utc and manually applying a format).

All 11 comments

@srose4 I think your best way to support this is to convert the data to UTC before passing to the chart. Otherwise, we'd need to conditional all of the moment() calls as possibly also moment.utc()

@etimberg Whether I use moment() or moment.utc(), the date is stilled displayed with local browser time zone conversion. If you inspect the first date object, time is 3am(gmt). However it is displayed on my graph as EST and in PST in Cali. What I want is, No matter where the user is located, the graph should always display 3am for the first point on the x-axis. I'm trying to understand if this is a bug in my code, a bug in chart.js, or an item not well documented?

Hmmm, ok I will do some investigation and see what I can find

Yea this was sort of a problem for me as well. From poking about, it seems to be because the moment objects are converted to integer timestamps and passed to the Chart.Ticks.generators.time instead of preserving them. So inside the generator, moment( ) is called on the timestamp causing it to convert to local time.

The solution for anyone that doesn't care its global can just use the moment-timezone extension that allows setting the global default for moment( ) usage. i.e.

moment.tz.setDefault("UTC");

Well, I do care that the proposed fix is global and I need to include another lib and would appreciate if this is fixed in chart.js. This is rather fundamental.

+1

Using moment.utc gets me the correct time on the tooltip but the x-axis labels are still wrong.

xAxes: [ {type: 'time',time: { tooltipFormat: 'LT'}, ticks:{callback: function(value, index, values) {
          if (!values[index]) {return}
          return moment.utc(values[index]['value']).format('LT');
      }}}]

This gave me the format I want. No idea why the ticks formatting is independent of the tooltip formatting but this is a work around (ie recasting the original value back into a moment.utc and manually applying a format).

I've created issue https://github.com/chartjs/Chart.js/issues/5186 to consolidate the various pieces of feedback we've received regarding time zone support. I'm going to close this issue in favor of that one. Please feel free to subscribe to it for update

@marekr is there anything more to just importing moment-timezone and calling

moment.tz.setDefault("America/New_York"); // in my case

I've experimented and the chart seems to ignore it. I was expecting the time series to update with the +5 hours (from NY). ❓

There's quite a bit more to it. Chart.js needs substantial updates. I'm working on it, but trying to do it without including moment-timezone to reduce download size. I have a couple different ideas. One is to add timezone support to date-fns and switch to that. I have a PR open with date-fns for that

I found a solution to this problem, but we need to revise a line of code in chart.js manually.
Go to .\node_modules\charts.js\src\scales\scales.time.js and find the function called convertTicksToLabels. The reason why the chart.js displays charts according to your local machine time is this function converts labels into moment objects.
So all we need to do is just add an offset to the moment object whenever the function tries to convert labels into moment objects.

Here is an example:
var givenTime = moment();
// it will display your local machine time. e.g. Thu May 03 2018 22:53:26 GMT+0800
var convertedTime = moment(givenTime.utc()).utcOffset(-180);
// e.g Thu May 03 2018 11:53:26 GMT-0300

More explicitly speaking, find the convertTicksToLabels function and do the following changes:
from (.node_modules\charts.js\src\scales\scales.time.js line 677, this may vary depends on the version of chart.js)
labels.push(this.tickFormatFunction(moment(ticks[i].value), i, ticks));
to
labels.push(this.tickFormatFunction(moment(moment(ticks[i].value).utc()).utcOffset(-180), i, ticks));

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nanospeck picture nanospeck  ·  3Comments

benmccann picture benmccann  ·  3Comments

adriantombu picture adriantombu  ·  3Comments

SylarRuby picture SylarRuby  ·  3Comments

longboy picture longboy  ·  3Comments