2017-07-28 17 views
1

我一直在研究一个需要随着时间进行大量计算的应用程序。gmdate在服务器之间不是不变的?

为了使一切工作一个应该,我开始:

$dateToday = strtotime(gmdate("m/d/y")); 

我的理解,这是应该返回GMT日期。因此,无论服务器在哪个时区,我都应该得到同样的时间?

所以,我在本地主机上的一切发展顺利的工作,但是当我在不同的时区移动到服务器,我开始变得问题。

Echo'ing“$ dateToday” localhost上给了我“1501192800”,而做同样的我得到“1501214400”在服务器上。 这与我的本地机器和服务器之间的6小时差异相同。

那么我在这里错过了什么?

感谢

+0

使用DateTime(http://php.net/manual/en/class.datetime.php) – Neodan

+1

*“那么我在这里错过了什么?*” - 很好的阅读和理解什么时区是什么以及它们是如何影响时间计算以及PHP [日期/时间函数](http://php.net/manual/en/ref.datetime.php)的知识。我建议你阅读有关它们,但不要使用它们。改用['DateTime'](http://php.net/manual/en/class.datetime.php)和相关的类。它们更易于使用,并为时区提供了完整的支持(而旧的日期/时间函数则不支持。) – axiac

+0

示例:date_default_timezone_set('Europe/Berlin'); –

回答

2
$dateToday = strtotime(gmdate("m/d/y")); 

我的理解,这是应该返回GMT日期。

根本不是。

gmdate()格式使用GMT时区的日期。由于您只用一个参数调用它,因此通过调用time()来获取格式化日期。

time()返回当前时间戳,即因为Jan 1, 1970, 0:00:00 UTC经过的秒数。

然后,gmdate()使用您在制作第二个参数的文本表示(当前时间戳正如我们看到的)第一个参数提供的格式。 gmdate("m/d/Y")返回的值为07/28/2017

然后,07/28/2017传递给strtotime(),试图将其解释为日期并从中计算时间戳。由于它不包含任何时间组件,因此strtotime()假定时间为0:00:00

这里来的渔获物。由于提供的字符串也不包含任何时区信息,因此PHP使用其配置来假定时区。正如您已经发现的,由于配置不同,在两台服务器上运行代码可能会产生不同的结果。

对于我来说,strtotime(gmdate('m/d/Y'))回报1501200000这是当今天(July 18, 2017)开始对UTC时区的时间戳(时间中的时刻)(因为我用于测试的PHP使用“UTC”为default timezone)。您在不同服务器上获得的值是今天在各自时区开始的时刻。

如果我使用正确配置为我的时区的PHP运行相同的代码(Europe/Bucharest),我得到1501189200。在UTC之前的值为10800秒,因为Europe/Bucharest目前在UTC+3(东欧标准时间的正规+2加上1小时,因为夏令时。

PHP目前提供一套良好的类来处理日期和时间:DateTime和其他类的名字与Date开始(寻找他们的文档中)。他们比旧的date & time functions更容易使用,他们也知道如何处理时区(旧功能不知道)。

创建DateTime对象存储在UTC时区今天开始是那么容易,因为:

$dateToday = new DateTime("today 0:00:00", new DateTimeZone("UTC")); 

您可以和创建一个DateTime对象为“现在”(中所需的时区),然后设置它的时间0:00:00

$dateToday = new DateTime("now", new DateTimeZone("UTC")); 
$dateToday->setTime(0, 0, 0); 

对于未在代码修改DateTime对象(它们是只读),那么你最好创建DateTimeImmutable对象。这个类可以防止它存储的值的意外改变。

+0

谢谢,我用 $ dateToday = new DateTime(“today 0:00:00”,new DateTimeZone(“UTC”)); $ dateGMTUnixToday = $ dateToday-> format('U'); 现在得到一个恒定的1501200000! 真的很感谢详细的解释。 – VoidZA

+0

@VoidZA如果你喜欢这个答案,那么赶快行动吧。如果它确实有帮助,然后接受它 – RiggsFolly

+0

我没有足够的代表upvote,也没有看到“接受”按钮。 – VoidZA

相关问题