以UTC格式存储日期和时间,并在PHP / MySQL中转换它们的本地时间

时间:2012-02-19 20:33:44

标签: php mysql timestamp utc datetime-conversion

我想问一下这是否会起作用,然后我再进行了一个关于我如何处理日期和时间的完全重构。

提出问题,这是我的问题...... 我将用户在“历史记录”表中执行的“操作”存储起来。这些操作有一个时间戳。用户可以来自世界各地,因此具有不同的时区。我想在历史记录中显示项目并在当地时区显示时间戳。

此外,我知道我可以使用日期时间字段并只存储UTC时间格式,但我选择使用时间戳,因此我可以将默认值设置为当前时间。

这会解决我的问题吗?

  1. 我的服务器时区将是洛杉矶

  2. 将时间戳存储为MySQL中的时间戳。我的理解是时间戳总是存储为UTC。记录将默认存储为creation_date或者我将显式设置UTC_TIMESTAMP()。有效地,数据库中的所有记录都将是UTC。

  3. 当用户登录时,我将获取他们的时区(我将其作为用户设置存储在数据库中)。 对于这个例子,假设这个人在纽约。

  4. 这是我的问题所在。这些都可以吗?

    1. a)抓取历史数据。所有时间戳都将自动从UTC转换为洛杉矶时间。 Foreach历史记录项,将洛杉矶时间戳转换为纽约时间戳并回显。
    2. OR

      1. b)将php时区“date_default_timezone_set”设置为纽约。抓取历史数据。所有时间戳在洛杉矶仍然是服务器时间仍然是洛杉矶时间。 Foreach历史记录项,只是回显时间戳,因为“date_default_timezone_set”会自动将洛杉矶时间戳转换为纽约。
      2. 选项4b是否有效?有没有更好的方法从洛杉矶时间转换到纽约时间?

        一般来说,有更好的方法吗?

4 个答案:

答案 0 :(得分:5)

你是对的,Unix时间戳总是以UTC格式。如果以UTC格式存储数据库中的时间戳,则只需在本地时间输出时间,就可以将PHP中的时区更改为用户本地的时区。您无需对时间戳进行任何转换。

<?php

$timeStampFromDatabase = 1325448000;  // 01 Jan 2012 20:00:00 GMT

date_default_timezone_set('America/Los_Angeles');
echo date('r', $timeStampFromDatabase); // Sun, 01 Jan 2012 12:00:00 -0800

date_default_timezone_set('Asia/Hong_Kong');
echo date('r', $timeStampFromDatabase); // Mon, 02 Jan 2012 04:00:00 +0800

您可以动态更改时区并继续以日期格式输出时间戳,并根据PHP中设置的时区“转换”它们。它非常简单,您不需要进行任何特殊处理,只要您在输出日期之前执行此操作,设置时区并不重要,但您可以在设置时区之前阅读它们。

答案 1 :(得分:3)

不幸的是,“date_default_timezone_set”没有像我想象的那样工作。根据前面的示例,如果我使用的日期已经是unix时间戳格式,它将起作用。然而,它们被格式化为“Y-m-d H:i:s”,唯一可以改变的是GMT偏移,这显然不起作用。

经过几个小时的烦躁不安,这就是我能够处理时间转换的方式。

$datetime = new DateTime($date_to_convert);
$usertimezone = new DateTimeZone($_SESSION['timezone']); //each user has their own timezone i store in a session (i.e. - "Americas/Los_Angeles")
$datetime->setTimezone($usertimezone);
echo $datetime->format("Y-m-d H:i:s");

我想我也可以做到以下几点:

Pseudo code
strtotime($datetime)
date_default_timezone_set($user_timezone)
echo date(format, $datetime)

以上,我认为,会强制日期函数在给定的$ user_timezone中处理它的逻辑。事后来说,我必须翻译每个$ datetime - &gt; unix_timestamp - &gt; $ datetime_converted,听起来并不比我选择的要好得多。

答案 2 :(得分:1)

始终将您的时间戳以UTC格式存储在数据库中。这是一个独立的时区和夏令时。要在时区中将其显示回用户,只需执行以下操作:

$users_timezone = 'Europe/London'; // See PHP documentation for names that can be used.
$date = new DateTime();
$date->setTimestamp($timestamp_from_database);
$date->setTimezone(new DateTimeZone($users_timezone));   
echo $date->format("H:ia jS F Y");

答案 3 :(得分:0)

默认情况下,Unix时间戳始终为UTC。如果我们以UTC格式将时间戳存储在数据库中,我们只需要使用以下PHP脚本:

<?php

$TZ_UTC = new DateTimeZone('UTC'); //-->Database Timezone;
$TZ_LOCAL = new DateTimeZone('America/New_York'); //-->Expected Local Timezone from user settings;

//--Example Database Query--
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
    //---If we want to show UTC timezone directy----
    echo $row['action_timestamp'];

    //---If we want to show LOCAL timezone from user settings----
    $dateObj = new DateTime($row['action_timestamp'], $TZ_UTC);
    $dateObj->setTimezone($TZ_LOCAL); //--> Here is the conversion!
    echo $dateObj->format("Y-m-d H:i:s T");
}
?>