我有一个角度应用程序,使用highcharts ng来制作折线图。y轴是数字,x轴是日期时间。
当使用moment.js.在"美国/纽约"one_answers"欧洲/伦敦"这两个时区之间转换时,我正试图正确解释夏令时的变化
伦敦目前处于英国夏令时(截至发贴时),因此是+1:00。
tick.TimeStamp
> "2015-04-21T16:06:06.0786392-04:00"
tick.TimeStamp是我的"美国/纽约"时间(目前在美国东部时间)。我用…把它转换成伦敦时间。。。
moment(tick.TimeStamp).tz("Europe/London").format()
> "2015-04-21T21:06:06+01:00"
我需要我在Unix Epoch ticks中的结果来在highcharts ng中为x轴绘制它们,所以我使用。。。
var d = moment(tick.TimeStamp).tz("Europe/London").format()
moment(d).valueOf()
产生
1429646766000
问题是,作为日期时间的刻度值结果是
2015年4月21日星期二20:06:06 GMT
应该是的位置
2015年4月21日星期二21:06:06 GMT
因为伦敦目前处于BST+1:00
是我做错了什么,还是moment只是计算错误了?
如有任何帮助,我们将不胜感激。非常感谢。
编辑:我应该提到,我的moment-timezones.js是他们网站上最新的时区信息。
Moment计算正确。
Tue, 21 Apr 2015 20:06:06 GMT
、Tue, 21 Apr 2015 21:06:06 BST
和Tue, 21 Apr 2015 16:06:06 EDT
都引用相同的时间,并且都具有相同的unix时间戳。当您调用.tz()
时,您只是在更改时间的格式。您不会更改实际时间。
注意:要获得unix时间戳,可以使用.unix()
,例如
moment(tick.TimeStamp).unix()
或者这将返回相同的值
moment(tick.TimeStamp).tz("Europe/London").unix()
我更新了一个JS fiddle来提供一个示例。http://jsfiddle.net/x0z90vqg/(如果不使用HighStock,则在xAxis上显示type
属性的更新小提琴)
我认为您的问题是没有正确使用Highcharts全局对象的属性useUTC和时区偏移属性。使用highcharts-ng
控件可以屏蔽Highcharts库的一些功能,但您仍然可以很容易地访问所需的功能。
小提琴的相关部分是:
Highcharts.setOptions({
global : {
useUTC : false,
timezoneOffset: -5
}
});
$scope.chartConfig.getHighcharts().redraw();
上面的示例将Highcharts全局对象设置为不使用UTC作为日期/时间序列,并将偏移量设置为-5小时(您可以像现在这样使用moment.js来获得所需的偏移量),然后告诉图表通过highcharts-ng
的公开getHighcharts()
方法重绘。该方法返回实际的图表对象,从那里开始,就像您直接使用高图,而不是通过任何中间组件。
编辑
@马特提出了一个很好的观点。像这样设置时区偏移与设置真正的时区并不完全相同。真正的时区将考虑夏令时的变化,因此,这只是与UTC的静态偏移。这样设置UTC偏移也会影响整个图形,而不仅仅是一个系列。如果您需要在不同时区的同一图表上显示(和比较)两个或多个系列,并将该数据显示为各自的时区,则可以启用多个X轴,并在每个轴的格式标签逻辑中,取刻度的X值,并通过javascript函数将其转换为要显示的时区值和标签。这将导致两个X轴的标签位于两个不同的时区,但图形中心部分的数据使用相同的UTC刻度。如果这样做,您可能还想覆盖工具提示弹出窗口的格式化程序,这样,如果您不希望它显示UTC,您就可以转换工具提示中显示的值,以显示每个点的时区值。
所有这些仍然不能解决显示跨越DST切换点的时间序列数据的问题。我不相信Highcharts有任何方式来表示这一点,我也不知道还有其他图表库可以这样做。这似乎是一个相当常见的问题,所以我相信它已经在某个地方得到了解决。。。
只是想发布一个我发现的快速更新。由于我在客户端尝试这样做时遇到了很多怪癖,我在控制器代码(.NET)中找到了一种在服务器端处理这一问题的好方法。我现在不再只返回时间戳(tick.timestamp),而是返回EasternTimeStamp和LondonTimeStamp我能够使用TimeZoneInfo类中的一个很好的方法来实现这一点。
/// <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;
}
希望任何遇到这个问题的人都能发现这很有用。在过去的一周里,我发现试图找到一种很好的方法来处理夏令时和这样的时区是很有压力的。