我正处于构建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
答案 0 :(得分:0)
您必须面对以下有关PHP和MySQL的限制:
MySQL没有任何列类型允许存储带有时区信息的本地时间。
PHP无法将复杂的数据类型(例如DateTime
实例)传递给MySQL,所有内容都需要进行字符串化,并且MySQL没有语法来传递带有时区信息的日期文字。< / p>
在实践中,它并没有看起来那么糟糕,因为您通常不需要插入信息的用户的当地时间:您只需要知道存储日期所指的确切时刻和( (可选)必须显示存储日期的时区。基本上有三种明智的方法可以做到这一点:
使用不受时区影响的格式,例如存储为INT
的Unix时间戳。
使用带有显式时区信息的日期列类型,例如一个TIMESTAMP
列(不要与Unix时间戳混淆),其中时区总是UTC。
使用具有隐式时区信息的日期列类型,例如DATE
或DATETIME
列,您决定所有日期都属于给定时区,可能是UTC。
#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)