在PHP / MySQL中将日期时间存储为UTC

时间:2009-08-28 20:49:20

标签: php mysql timezone

我读到的关于将时间转换为用户时区的地方说,最好的方法是以UTC格式存储日期和时间,然后将用户的时区偏移量添加到此时间。

如何以UTC时间存储日期?我使用MySQL DATETIME字段。

在我的PHP代码中向MySQL添加新记录时,我会使用now()插入MySQL DATETIME。

我是否需要使用与now()不同的内容来存储UTC时间?

6 个答案:

答案 0 :(得分:43)

MySQL:UTC_TIMESTAMP()

  

返回当前的UTC日期和时间   作为'YYYY-MM-DD HH:MM:SS'中的值或   YYYYMMDDHHMMSS.uuuuuu格式,   取决于功能是否   用于字符串或数字上下文

PHP:gmdate()

PHP中还使用PHP date_default_timezone_set()来设置脚本的当前时区。您可以将其设置为客户端时区,以便所有格式化函数以当地时间返回时间。

事实上,虽然我很难让这个工作,并总是绊倒一些陷阱。例如。从MySQL返回的时间信息未格式化为“UTC”,因此如果您不小心,strtotime会将其转换为本地时间。我很想知道某人是否有针对此问题的可靠解决方案,当日期遍历媒体边界时不会破坏(HTTP-> PHP-> MySQL和MySQL-> PHP - > HTTP),也考虑了XML和RSS / Atom。

答案 1 :(得分:40)

我建议在UTC时区插入日期。这将为您节省很多令人头疼的问题。

INSERT INTO abc_table (registrationtime) VALUES (UTC_TIMESTAMP())

当我查询我的数据时,我使用以下PHP脚本:

<?php

while($row = mysql_fetch_array($registration)) { 

  $dt_obj = new DateTime($row['message_sent_timestamp'] ." UTC");
  $dt_obj->setTimezone(new DateTimeZone('Europe/Istanbul'));
  echo $formatted_date_long=date_format($dt_obj, 'Y-m-d H:i:s');
}
?>

您可以将DateTimeZone值替换为可用的PHP timezones之一。

答案 2 :(得分:7)

NOW()为您提供运行数据库的系统的时间(包括时区偏移量)。要获得UTC日期/时间,您应使用MySQL Reference Manual中描述的UTC_TIMESTAMP()

答案 3 :(得分:6)

https://dba.stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp

如果删除,请从上面的链接中引用所有答案:

与@ ypercube的评论一致CURRENT_TIMESTAMP以UTC格式存储但作为当前时区检索,您可以使用--default_time_zone选项影响服务器的时区设置以进行检索。这使您的检索始终为UTC。

默认情况下,选项为“SYSTEM”,这是您的系统时区设置方式(可能是也可能不是UTC!):

mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM             | SYSTEM              |
+--------------------+---------------------+
1 row in set (0.00 sec)

mysql> SELECT CURRENT_TIMESTAMP();
+---------------------+
| CURRENT_TIMESTAMP() |
+---------------------+
| 2012-09-25 16:28:45 |
+---------------------+
1 row in set (0.00 sec)

您可以动态设置:

mysql> SET @@session.time_zone='+00:00';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM             | +00:00              |
+--------------------+---------------------+
1 row in set (0.00 sec)

或永久在你的my.cnf:

[mysqld]
**other variables**
default_time_zone='+00:00'

重新启动服务器,您将看到更改:

mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| +00:00             | +00:00              |
+--------------------+---------------------+
1 row in set (0.00 sec)

mysql> SELECT CURRENT_TIMESTAMP();
+---------------------+
| CURRENT_TIMESTAMP() |
+---------------------+
| 2012-09-25 20:27:50 |
+---------------------+
1 row in set (0.01 sec)

答案 4 :(得分:2)

正如@Haluk建议的那样,您可以将日期存储为UTC datetime。 当你想要插入的日期来自PHP代码,并添加一些有关它如何工作的细节时,我补充了他的答案:

$pdo = new PDO('mysql:host=mydbname.mysql.db;dbname=mydbname', 'myusername', 'mypassword');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$insertStmt = $pdo->prepare("insert into test (last_modified)"
    ." values(:last_modified)");
$insertStmt->bindParam(':last_modified', $lastModified, PDO::PARAM_STR);
$lastModified = gmdate("Y-m-d H:i:s");
$insertStmt->execute();

实际上PHP中的datetime没有与之关联的时区。传递给PDO的只是一个字符串,采用MySQL认可的格式之一,代表UTC时区的日期。例如,如果日期为2015-10-21 19:32:33 UTC+2:00,则上面的代码只是告诉MySQL插入2015-10-21 17:32:33gmtdate("Y-m-d H:i:s")以这种格式为您提供当前日期。在任何情况下,您需要做的就是构建表示您希望以UTC时间插入的日期的字符串。

然后,当您阅读日期时,您必须告诉PHP您刚刚检索的日期的时区是UTC。请使用Haluk的答案中的代码。

答案 5 :(得分:0)

随机:UTC_TIMESTAMP(6)表示6位数微秒的时间。

MySQL 5.7 +