首页 文章

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

提问于
浏览
43

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

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

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

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

6 回答

  • 6

    MySQL:UTC_TIMESTAMP()

    以“YYYY-MM-DD HH:MM:SS”或YYYYMMDDHHMMSS.uuuuuu格式返回当前UTC日期和时间,具体取决于函数是在字符串还是数字上下文中使用

    PHP:gmdate()

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

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

  • 43

    我建议在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之一 .

  • 7

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

  • 2

    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)
    
  • 0

    正如@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:33 . gmtdate("Y-m-d H:i:s") 以这种格式为您提供当前日期 . 无论如何,您需要做的就是在UTC时间内构建表示要插入日期的字符串 .

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

  • 40

    随机: UTC_TIMESTAMP(6) 用于6位数微秒的时间 .

    MySQL 5.7

相关问题