php mysql UTC时间戳

时间:2016-12-27 15:26:20

标签: php mysql datetime

我正处于构建mysql表的早期阶段,该表将保存来自两个时区的数据。我的机器和服务器都在America / Los_Angeles时区。时区表没有加载到mysql服务器中,但是在这个站点的其他地方,我已经读过这个没有必要,只要php处理查询 - php会将UTC偏移写入mysql。 Mysql数据类型是TIMESTAMP。已使用包含以下语句的php脚本插入示例数据:

        if($company == 'HOS_CIN' or $company == 'HOS_FER') {
        date_default_timezone_set("America/New_York");
    }

然后使用两个php脚本在浏览器中显示数据。一个包括上述声明,一个没有。带有语句的那个​​显示时间为中午EST,而没有显示时间为PST中午。如果mysql存储了UTC偏移量,那么显示的时间不应该有三小时的差异吗?

Php版本5.3.3,mysql版本5.0.95

1 个答案:

答案 0 :(得分:0)

您必须面对以下有关PHP和MySQL的限制:

  • MySQL没有任何列类型允许存储带有时区信息的本地时间。

  • PHP无法将复杂的数据类型(例如DateTime实例)传递给MySQL,所有内容都需要进行字符串化,并且MySQL没有语法来传递带有时区信息的日期文字。< / p>

在实践中,它并没有看起来那么糟糕,因为您通常不需要插入信息的用户的当地时间:您只需要知道存储日期所指的确切时刻和( (可选)必须显示存储日期的时区。基本上有三种明智的方法可以做到这一点:

  1. 使用不受时区影响的格式,例如存储为INT的Unix时间戳。

  2. 使用带有显式时区信息的日期列类型,例如一个TIMESTAMP列(不要与Unix时间戳混淆),其中时区总是UTC。

  3. 使用具有隐式时区信息的日期列类型,例如DATEDATETIME列,您决定所有日期都属于给定时区,可能是UTC。

  4. #2和#3之间的区别在于MySQL是否知道时区,或者只有你和你的代码才知道。

    无论您选择哪种方法,都必须指示预期进行时区转换的所有程序,以了解使用的时区:

    • PHP需要时区来生成/显示Unix时间戳,并从/转换为用户键入/期望的本地时间以及MySQL预期/打印的时间,例如:

      $user_date = new DateTime('2016-10-03 00:00:00', new DateTimeZone('Europe/Berlin'));
      $user_date->setTimezone(new DateTimeZone('UTC'));
      echo $user_date->format('c');
      
    • 当您使用TIMESTAMP列时,MySQL需要时区来转换/到当地时间,例如:

      mysql> create table foo(
          -> foo int(10) unsigned auto_increment,
          -> my_date timestamp,
          -> primary key (foo)
          -> );
      Query OK, 0 rows affected (0.00 sec)
      
      mysql> set @@time_zone = '+01:00';
      Query OK, 0 rows affected (0.00 sec)
      
      mysql> insert into foo (my_date) values ('2016-12-27 18:50:00');
      Query OK, 1 row affected (0.00 sec)
      
      mysql> set @@time_zone = '-07:00';
      Query OK, 0 rows affected (0.00 sec)
      
      mysql> insert into foo (my_date) values ('2016-12-27 18:50:00');
      Query OK, 1 row affected (0.00 sec)
      
      mysql> select * from foo order by 1;
      +-----+---------------------+
      | foo | my_date             |
      +-----+---------------------+
      |   1 | 2016-12-27 10:50:00 |
      |   2 | 2016-12-27 18:50:00 |
      +-----+---------------------+
      2 rows in set (0.00 sec)
      
      mysql> set @@time_zone = '+09:30';
      Query OK, 0 rows affected (0.00 sec)
      
      mysql> select * from foo order by 1;
      +-----+---------------------+
      | foo | my_date             |
      +-----+---------------------+
      |   1 | 2016-12-28 03:20:00 |
      |   2 | 2016-12-28 11:20:00 |
      +-----+---------------------+
      2 rows in set (0.00 sec)