5

我在 GMT 时间 [2013-07-19 10:12:56] 的 MySQL 数据库中有一个时间戳。我知道它应该作为 DateTime 和 UTC 在数据库中,但不幸的是它就是这样。

我需要提取时间戳并传递给 JavaScript [HighCharts]。

$time = strtotime('2013-07-19 10:12:56');
echo("Converting to UNIX Time: ");echo $time;
echo("Converting to JS Time: ");echo ($time*1000);

由于 JavaScript 需要以毫秒为单位的时间,因此乘以购买 1000

输出:转换为 UNIX 时间:1374253976

输出:转换为JS:时间:1374253976000

我的问题是为什么它在 HighCharts 中显示为 17.12

当我将 1374253976000 放入http://www.epochconverter.com时,我得到:
GMT:Fri, 19 Jul 2013 17:12:56 GMT,这是不正确的。数据库中显示的时间应该是 10:12:56。

任何想法为什么它会是 7 小时?

4

4 回答 4

11

EpochtimeconverterFri, 19 Jul 2013 10:12:56 GMT有以下纪元时间

Epoch timestamp: 1374228776 
Timestamp in milliseconds: 1374228776000
Human time (GMT): Fri, 19 Jul 2013 10:12:56 GMT
Human time (your time zone): Friday, July 19, 2013 3:42:56 PM

请注意,这不是 1374253976你得到的。这就是问题所在,从 epochtime 到 highcharts 等的转换是正确的。这是你的时代错误

除非另有说明,否则 PHP 会将字符串视为在服务器的时区中。试一试,明确指定时区GMT,如下所示

$time = strtotime('2013-07-19 10:12:56' . ' GMT');
echo("Converting to UNIX Time: ");echo $time;
echo("Converting to JS Time: ");echo ($time*1000);

您观察到的 7h 差异可能是因为您的服务器位于时区 -7 ?

于 2013-07-26T18:23:49.560 回答
2

问题 #1

主要问题是在您的转换步骤中使用strtotime. PHP 尝试猜测时间字符串与时区的关系(可能使用您的时区),但在您的情况下,它需要知道更多才能正确猜测。您可以通过明确告诉 PHP 时间字符串表示为 GMT(格林威治标准时间)来做到这一点。

由于您的数据库只有 YYYY-MM-DD HH:MM:SS 的形式,因此您可以在strtotime调用期间将必要的 GMT 标识符连接到它上面。

$time = strtotime('2013-07-19 10:12:56' . ' GMT');

例如:

<pre>
<?php
    $time = strtotime('2013-07-19 10:12:56' . ' GMT');
    echo("Converting to UNIX Time: $time\n");
    echo("Converting to JS Time: ");
    echo ($time*1000);
?>
</pre>

转换为 UNIX 时间:1374228776
转换为 JS 时间:1374228776000

将生成的 UNIX 时间粘贴到 Epoch Converter 中会正确导致GMT: Fri, 19 Jul 2013 10:12:56 GMT

问题 #2

如上所述更改您的 PHP 代码是必要的,但由于它不能完全为您工作,我可以看到您还有一个问题正在发生。(塞巴斯蒂安试图帮助你解决这个问题。)

我要添加到 Sebastian 的评论中的是,在您的 JavaScript 中创建任何图表或图表对象之前,需要配置全局设置。否则它们对这些图表的输出没有影响。因此,您需要确保在代码中存在任何图表对象之前应用以下配置。

Highcharts.setOptions({
    global: {
        useUTC: false
    }
});

(如果您不使用此配置,您的图表仍然可以正常工作,但日期和时间将显示相对于格林威治标准时间,而不是每个查看图表的用户的本地时区。)

讨论(放在后面,讨厌讨论的人不用看):

我验证了如果您按照上述建议修改您的 PHP 代码,那么您现在将正确的 UTC/GMT 数字纪元时间传递给 JavaScript。您可以使用以下代码确认 100%:

Date.UTC(2013, 6, 19, 10, 12, 56)
1374228776000
new Date(1374228776000).toUTCString()
"Mon, 19 Aug 2013 10:12:56 GMT"

您显然面临的第二个问题是双重的:让 Highcharts 正确地将其解释为 UTC/GMT 值,而不是来自其他(例如本地)时区的值,并告诉 Highcharts 以您想要的格式正确输出时区。

使 Highcharts 正确解释您的时间数字:默认情况下,Highcharts 假定像这样的数字时间数据采用 UTC [[1331028000000, 5], [1331031600000, 6], [1331035200000, 4]]。除非你的 JavaScript 中潜伏着一些奇怪的东西并改变了时间数据的处理方式,否则你应该在这方面做得很好。

使 Highcharts 在您的图表上以人类可读的日期显示正确的时间:这是您应该密切关注 API 的地方:http: //api.highcharts.com/highcharts#global.useUTC

顺便说一句,Sebastian Bochan 是 Highcharts 支持团队的成员,所以你当然可以相信他的评论。

于 2013-07-26T20:49:43.437 回答
0

其实不是JS的问题。诀窍在于 PHP 以及“strtotime”如何根据默认时区进行转换。

在您的示例中,时间戳的计算方式就像您在“America/Los_Angeles”时区一样,因此您获得1374253976的是秒数,而不是1374228776时区“GMT”。由于您在 epochconverter 上将时间戳转换为相对于 GMT 时区,因此会出现“不匹配”。

您存储在 MySQL 中的数据是 GMT,您的 PHP 安装的时区是“America/Los_Angeles”。当您“strtotime”时,您将数据解释为 MYSQL 不是 GMT 而是 America/Los_Angeles。这就是为什么两者之间有7个小时的时间。

这是一个小脚本来更好地解释这一点:

date_default_timezone_set('GMT');

echo strtotime('2013-07-19 10:12:56', time() - 10) . "\n";

date_default_timezone_set('America/Los_Angeles');

echo strtotime('2013-07-19 10:12:56', time() - 10) . "\n";

将显示:

1374228776 // from epochconverter : Fri, 19 Jul 2013 10:12:56 GMT
1374253976 // from epochconverter : Fri, 19 Jul 2013 17:12:56 GMT

注意序列“287”是如何被序列“539”替换的。

在 PHP 中,几乎每个处理时间的函数都将根据当前定义的时区进行操作。

查看此以获取更多信息:

PHP 默认时区

于 2013-07-29T13:19:54.823 回答
0

你有一个时区问题。在格林威治标准时间,时间戳2013-07-19 10:12:56转换为1374228776纪元后的秒数:http: //jsfiddle.net/hsvtE/

但是,您的 PHP 脚本会返回不正确的 unix 时间:

输出:转换为 UNIX 时间:1374253976

如您所见,两个时间戳之间的区别是:

 1374253976 (incorrect)
-1374228776 (correct)
-----------
      25200 seconds

您的 PHP 脚本返回的25200时间比 GMT 时间提前几秒(或七个小时)。PHP 返回错误时间的原因是strtotime函数的工作方式。

如果时间戳中未指定时区,则strtotime假定时间戳属于默认时区。

有两种方法可以解决这个问题:

方法一:设置默认时区为GMT

您可以使用函数date_default_timezone_get和获取和设置 PHP 中的默认时区date_default_timezone_set。使用这两个函数,您可以为时间戳设置正确的时区,如下所示:

function get_time($timestamp, $timezone = 'GMT') {
    $default_timezone = date_default_timezone_get(); // get current timezone
    date_default_timezone_set($timezone);            // set correct timezone
    $time = strtotime($timestamp);                   // get correct time
    date_default_timezone_set($default_timezone);    // reset original timezone
    return $time;                                    // return correct time
}

现在您可以通过简单地调用get_time而不是strtotime

$time = get_time('2013-07-19 10:12:56');

我建议您使用此方法,因为如果时间戳已经指定了一个时区,那么strtotime只需忽略默认时区并改用指定的时区。

方法2:在时间戳本身中指定时区

第二种方法要短得多:

function get_time($timestamp, $timezone = 'GMT') {
    return strtotime($timestamp . ' ' . $timezone);
}

$time = get_time('2013-07-19 10:12:56');

但是,我建议您改用第一种方法,因为它更安全。例如,如果您提供了时间戳2013-07-19 10:12:56 EST,则上述函数将strtotime使用具有两个时区的字符串调用 - 2013-07-19 10:12:56 EST GMT

结论

这个简单的更改应该可以解决您的问题。如果您想要以毫秒为单位的时间,那么只需将时间乘以1000

$time = 1000 * get_time('2013-07-19 10:12:56');

我假设您的客户端代码是正确的。因此,如果你仍然有问题,那么你应该看看你的 JavaScript。

于 2013-07-27T17:10:25.027 回答