admin管理员组文章数量:1290991
I have an angular application using highcharts-ng to make a line graph. The y-axis is numbers and the x-axis is datetime's.
I am trying to properly account for Daylight Savings Time changes when converting between the two timezones of "America/New_York" and "Europe/London" using moment.js.
London is currently in BST (as of the time of posting this), so it is +1:00.
tick.TimeStamp
> "2015-04-21T16:06:06.0786392-04:00"
tick.TimeStamp is my "America/New_York" time (currently in EDT). I convert that to London time using...
moment(tick.TimeStamp).tz("Europe/London").format()
> "2015-04-21T21:06:06+01:00"
I need my result in Unix Epoch ticks to plot them for the x-axis in highcharts-ng, so I use...
var d = moment(tick.TimeStamp).tz("Europe/London").format()
moment(d).valueOf()
which yields
1429646766000
The issue is that this tick value result as a datetime is
Tue, 21 Apr 2015 20:06:06 GMT
where it should be
Tue, 21 Apr 2015 21:06:06 GMT
since London is currently in BST +1:00
Am I doing something wrong, or is moment just calculating this incorrectly?
Any help would be greatly appreciated. Thank you!
EDIT: I should mention that my moment-timezones.js is the most recent from their site with all of the timezone info.
I have an angular application using highcharts-ng to make a line graph. The y-axis is numbers and the x-axis is datetime's.
I am trying to properly account for Daylight Savings Time changes when converting between the two timezones of "America/New_York" and "Europe/London" using moment.js.
London is currently in BST (as of the time of posting this), so it is +1:00.
tick.TimeStamp
> "2015-04-21T16:06:06.0786392-04:00"
tick.TimeStamp is my "America/New_York" time (currently in EDT). I convert that to London time using...
moment(tick.TimeStamp).tz("Europe/London").format()
> "2015-04-21T21:06:06+01:00"
I need my result in Unix Epoch ticks to plot them for the x-axis in highcharts-ng, so I use...
var d = moment(tick.TimeStamp).tz("Europe/London").format()
moment(d).valueOf()
which yields
1429646766000
The issue is that this tick value result as a datetime is
Tue, 21 Apr 2015 20:06:06 GMT
where it should be
Tue, 21 Apr 2015 21:06:06 GMT
since London is currently in BST +1:00
Am I doing something wrong, or is moment just calculating this incorrectly?
Any help would be greatly appreciated. Thank you!
EDIT: I should mention that my moment-timezones.js is the most recent from their site with all of the timezone info.
Share Improve this question edited Apr 21, 2015 at 22:51 Matt Johnson-Pint 242k75 gold badges463 silver badges608 bronze badges asked Apr 21, 2015 at 20:21 CoreyCorey 211 gold badge1 silver badge3 bronze badges 03 Answers
Reset to default 4Moment is calculating this correctly.
Tue, 21 Apr 2015 20:06:06 GMT
, Tue, 21 Apr 2015 21:06:06 BST
, and Tue, 21 Apr 2015 16:06:06 EDT
all refer to the same time and will all have the same unix timestamp. When you call .tz()
you are just changing how that time will be formatted. You aren't changing the actual time.
Note: To get the unix time stamp you can use .unix()
e.g.
moment(tick.TimeStamp).unix()
Or this will return the same value
moment(tick.TimeStamp).tz("Europe/London").unix()
I've updated a JS fiddle to provide a sample. http://jsfiddle/x0z90vqg/ (Updated fiddle showing type
property on xAxis if not using HighStock)
I believe your issue is that you're not using the Highcharts global object's properties useUTC and timezoneOffset properties appropriately. Using the highcharts-ng
control masks some of the capabilities of the Highcharts library, but you're still able to access the features you need pretty easily.
The relevant piece of the fiddle is:
Highcharts.setOptions({
global : {
useUTC : false,
timezoneOffset: -5
}
});
$scope.chartConfig.getHighcharts().redraw();
The above example sets the Highcharts global object to not use UTC for the date/time series and set's the offset to -5 hours (you can obtain the needed offset using the moment.js like you already are), and then telling the chart to redraw through the highcharts-ng
's exposed getHighcharts()
method. That method returns the actual chart object and from there it's like you're using highcharts directly and not through any intermediary ponent.
Edit
@Matt brought up a very good point. Setting the timezoneOffset like this isn't quite the same thing as setting a true timezone. A true timezone would take into account DST changes and such, this is just a static offset from UTC. Setting the UTC offset like this also affects the entire graph, not just one series. If you require displaying (and paring) two or more series on the same graph in different timezones, and displaying that data as their respective timezones, you can enable multiple X-axis and in the format label logic for each axis, take the X value for the tick and convert it via javascript function into the timezone'd value and label you want to display. This should result in two X-axis with labels in two different timezones, but the data in the central part of the graph running off the same UTC scale. If doing this, you would likely also want to override the formatter for the tool tip popup as well so that you can convert the value displayed in the tool tip to show the timezone'd value for each point if you didn't want it to display UTC.
All of this still doesn't solve the problem of displaying a time series of data that crosses over the point where DST switches. I don't believe Highcharts has any way of representing that, and I'm not aware of another charting library that does either. It seems like it would be a fairly mon problem though, so I'm sure it's been solved somewhere...
just wanted to post a quick update of what I figured out. Since I ran into lots of quirks trying to do this on the client side, I found a nice way to handle this on the server side in my Controller code (.NET). Instead of just returning the timestamp (tick.TimeStamp), I now return EasternTimeStamp and LondonTimeStamp. I was able to acplish this using a nice method off of the TimeZoneInfo class.
/// <summary>
/// Converts the time to eastern standard time.
/// This should properly account for DST, putting the time in EST (-5:00) or EDT (-4:00)
/// </summary>
public static DateTime ConvertTimeToEasternStandardTime(DateTime inputDateTime)
{
// US eastern timezone=Eastern Standard Time
string targetTimeZoneId = "Eastern Standard Time";
DateTime outputDateTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(inputDateTime, targetTimeZoneId);
return outputDateTime;
}
/// <summary>
/// Converts the time to GMT standard time.
/// This should properly account for DST, putting the time in BST (+1:00) or GMT (+0:00)
/// </summary>
public static DateTime ConvertTimeToGMTStandardTime(DateTime inputDateTime)
{
// London timezone=GMT Standard Time
string targetTimeZoneId = "GMT Standard Time";
DateTime outputDateTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(inputDateTime, targetTimeZoneId);
return outputDateTime;
}
Hopefully anyone who runs into this issue can find this useful. I've found it to be quite stressful trying to find a nice way to deal with DST and timezones like this over the past week.
本文标签: javascriptmomentjs timezones valueOf() not returning expected valuesStack Overflow
版权声明:本文标题:javascript - moment.js timezones .valueOf() not returning expected values - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741521187a2383193.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论