我有一个Ubuntu / Apache2 / PHP(Symfony2)/ MySQL日期问题。我认为这是一个系统问题,因为我没有在dev env中,只有rec和prod envs。当我发布一个包含日期时间的表单时,我输入的数据库比DB少2小时。当我阅读它时,屏幕上的日期时间与我在DB中的日期时间相同。 2小时的差异符合我的时区(欧洲/巴黎)。
开发环境:
rec / prod环境:
当我在两台机器上运行date -R
时,我有一个匹配项:Sat, 24 Sep 2016 19:39:53 +0200
,还有几秒钟的时间。更少,是我输入命令的时间。
/etc/timezone
在两台机器上都包含“Europe / Paris”。
在两台机器上,PHP的(CGI端)date.timezone也是“Europe / Paris”。
在两台计算机上,SQL查询SELECT @@global.time_zone, @@session.time_zone;
返回“SYSTEM”& “SYSTEM”
我使用bootstrap日期时间选择器,基于moment.js,输入此日期&时间。但我通过检查浏览器控制台中的POSTed数据并确认日期没有被更改,从嫌疑人中删除了它。
两台机器上的应用程序代码完全相同(相同的颠覆修订版)。
你看到别人要测试的东西吗?
答案 0 :(得分:1)
可能是因为this PR最近才合并。
尝试更改此
- $dateTime = new \DateTime(sprintf('@%s', $timestamp), new \DateTimeZone($this->outputTimezone));
+ $dateTime = new \DateTime(sprintf('@%s', $timestamp));
+ // set timezone separately, as it would be ignored if set via the constructor,
+ // see http://php.net/manual/en/datetime.construct.php
+ $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
在
DateTimeToLocalizedStringTransformerTest.php
请参阅this。
答案 1 :(得分:0)
PHP不使用系统时区。它有自己的内部时区设置date.timezone
可由PHP配置。它还有自己的internal timezone database依赖,而不是您的系统/etc/timezone
。
您可以在php.ini中全局配置时区,或在代码中本地配置时区(即使用date_default_timezone_set()
,使用PHP timezone identifiers之一。而不在{{{{}}中指定时区例如,构造函数,或者在传递给DateTime
等函数的参数中没有GMT偏移量时,PHP使用默认配置的strtotime
设置来选择时区。如果没有配置,它会回退到date.timezone
。
来自UTC
上的PHP手册:
按优先顺序,此函数返回默认时区:
使用
date_default_timezone_set()
函数(如果有)读取时区集仅限PHP 5.4.0之前:阅读
date_default_timezone_set()
环境变量(如果非空)读取
TZ
ini选项的值(如果已设置)仅限PHP 5.4.0之前:查询主机操作系统(如果支持且操作系统允许>)。这使用了一种必须猜测时区的算法。对于任何情况,这都无法正常工作。到达此阶段时会显示警告。不要依赖它正确猜测,而是将date.timezone设置为正确的时区。
如果以上都不成功,
date_default_timezone_get()
将返回UTC的默认时区。
因为你不使用PHP< 5.4.0,PHP将始终只查看date.timezone
设置,如果未设置,则回退到date.timezone
。
以时区无关的方式在客户端和服务器之间传输时间的最佳方法是在传输期间使用Unix时间戳(即UTC) ,并且仅在远程端进行转换。例如,将UTC
之类的内容发送到浏览器,并让您的Javascript使用time() * 1000
将其转换为格式日期/时间,这意味着最终用户会根据以下内容查看正确的日期/时间他们在本地的时区信息,但无论时区如何,您的服务器仍然会得到正确的时间。
因此,作为一般惯例,它是一个好主意:
Date
,strtotime()
等方式从服务器传输到客户端...)DateTime::getTimestamp()
)这样做可以确保时间格式和时区之间的转换与存储正确的时间分开,因为将时区转换应用于格式化日期然后不小心忘记或存储/传输错误时区。这就是为什么始终以时区不可知的方式进行传输可以防止破坏数据并且仅在该传输的终止端应用转换(如果需要)。然后PHP或Javascript可以使用Unix时间戳,但是当他们需要再次相互交谈时,他们可以转换回UTC / Unix时间戳并发送它。