Does PHP time() return a GMT/UTC Timestamp?
我只想检查time()是否返回UTC / GMT时间戳或我是否需要使用date_default_timezone_set()?
time返回UNIX时间戳,该时间戳与时区无关。由于UNIX时间戳表示自1970年UTC以来的秒数,您可以说它是UTC,但它确实没有时区。
要非常清楚,UNIX时间戳在任何给定时间都是全世界相同的值。在撰写时,它在东京,伦敦和纽约1296096875。要将此转换为"人类可读"时间,您需要指定要在哪个时区显示。1296096875在东京是2011-01-27 11:54:35,在伦敦它是2011-01-27 02:54:35,在纽约它是2011-01-26 21:54:35。
实际上,在处理时间时,您通常会处理(混合)这些概念:
-
绝对的时间点,我喜欢称之为人类历史的观点
-
当地时间,我喜欢称之为挂钟时间
-
以任何表示人类历史绝对点的格式的完整时间戳
-
当地挂钟时间不完整
像这样可视化时间:
1 2 3
| -------+-------------------+-------+--------+----------------+------>
| | | | |
Dinosaurs died Jesus born Y2K Mars colonised ??? |
(不按比例) sub>
此行上的绝对点可表示为:
-
1296096875
-
2011年1月27日02:54:35欧洲/伦敦
两种格式在不同的符号中表示相同的绝对时间点。前者是一个简单的计数器,大致在这里开始:
1 2 3 4 5
| start of UNIX epoch
|
-------+-------------------+------++--------+----------------+------>
| | | | |
Dinosaurs died Jesus born Y2K Mars colonised ??? |
后者是一个更复杂但同样有效和富有表现力的反制者,大致在这里开始:
1 2 3 4 5
| start of Gregorian calendar
|
-------+-------------------+-------+--------+----------------+------>
| | | | |
Dinosaurs died Jesus born Y2K Mars colonised ??? |
UNIX时间戳很简单。它们是一个从一个特定时间点开始并且每秒增加1的计数器(官方定义的是第二个)。想象一下,伦敦有人在1970年1月1日午夜开始制作秒表,现在仍在运行。这或多或少是UNIX时间戳。每个人都使用相同的秒表值。
人类可读的挂钟时间更复杂,而且它的缩写和日常使用中省略了部分内容,因此更加复杂。 02:54:35在上图所示的时间轴上几乎没有任何意义。 2011年1月27日02:54:35已经具体化了很多,但仍然可能意味着这条线上的各种不同点。"当时钟在2011年1月27日02:54:35在伦敦敲响时,欧洲"现在终于在这条线上绝对明确,因为只有一个时间点才是真的。
因此,时区是"挂钟时间"的"修饰符",它是使用日历和小时/分钟/秒表示法表达唯一的绝对时间点所必需的。没有时区,这种格式的时间戳是模棱两可的,因为时钟在2011年1月27日02:54:35在全球各个国家的不同时间发生。
UNIX时间戳本身不存在此问题。
要从UNIX时间戳转换为人类可读的挂钟时间,您需要指定您希望显示时间的时区。要从挂钟时间转换为UNIX时间戳,您需要知道挂钟时间的哪个时区应该是。您要么必须每次都包含时区与每次这样的转换,要么设置与date_default_timezone_set一起使用的默认时区。
-
你说的不是与自己发生冲突吗?"time返回一个UNIX时间戳,与时区无关......"然后"它将根据设置的时区计算,所以如果你的时区设置不正确,时间戳将会关闭......"认知不一致。
-
UNIX时间戳的格式与时区无关。 UNIX时间戳表示人类历史中唯一的绝对点。然而,为了从"挂钟时间"(例如"2011年1月26日21:54:35")到达该时间戳,需要考虑该挂钟时间的时区。我承认这一点有点不清楚。
-
我重写并澄清了一点。 :)
-
伟大的写作:)虽然我认为你可以简单地说UNIX时间戳不能有时区,因为它是一个数字。这不是约会。这是几秒钟。和号码,不能有任何时区。我认为这是时间戳的重点。
-
@jayarjo嗯,"约会"也是"只是数字"。 2011-01-27 02:54:35只是一堆数字,它们共同形成一个时间戳。问题在于这些数字是相对的。 2011-01-27相对于一个长发在很多个月前出生的男人。 02:54:35是相对于太阳和月亮在天空中可见的,它随位置而变化,因此需要时区说明符。 1296096875是相对于历史中任意固定点的数字,就像2011-01-27一样。
-
如果你说的是真的,时间戳应该根据默认的时区设置而有所不同......但事实并非如此!请检查这个问题。
-
@Flash No.计算机在UNIX内部运行时或类似的东西,它知道当前的绝对时间是多少。它不会在"人类可读的时区相关时间"上运行。您设置的时区仅影响您请求人类可读时间时打印的内容。如果你问它当前的绝对(UNIX)时间是什么,它总会给你相同的答案。
-
但是当你在BIOS中设置时间时,你设置hh:mm:ss,而不是时间戳,所以它必须以某种方式依赖于时区。问题是您可能不知道操作系统的时区,尤其是在某些虚拟机(如Android上的Bit Web Server)上工作时。
-
@Flash这取决于你的BIOS,我不知道你的BIOS做了什么。您是否更改了BIOS的时间以查看是否有所改变?事实是,PHP的date_default_timezone_set仅影响使用date()(或相关函数)时打印时间的时区,它实际上并不会将您的计算机传输到不同的时区。即使它确实如此,也不会改变当前的绝对(UNIX)时间。所有这些当然取决于正确设置系统的时间(和时区)。
-
使用tzselect和相同的日期时间在Debian上设置不同的时区会使时间戳不同。
-
@Flash当然,因为你已经改变了你的底层操作系统的基本绝对时间。如果你告诉你的系统它目前在澳大利亚并且它当前是早上8点,那么它会使用这些信息来确定它当前的绝对时间。而且,PHP的date_default_timezone_set不会做同样的事情。正如函数名称所暗示的那样,它设置使用date函数打印时间时使用的默认时区。它不会改变您的操作系统时间或PHP对时间的理解。它改变了为人类打印的格式时间。
-
但绝对时间(系统时钟)也不是绝对的。如果将它保留为unix时间戳,那么人们不会太担心千禧虫。好的... default_timezone_set不会影响它,但它应该。因为你永远不知道你所处的时区特别是在虚拟系统上,从系统时钟花费时间然后将其转换为给定的时区(这可能是错误的)。
-
@Flash不,BIOS时钟也不是绝对的。请参阅您在其他问题中的答案,了解操作系统如何处理该问题。千年虫与时区毫无关系。 date_default_timezone_set不会也不应该影响实际时间。你真的希望你的PHP脚本每隔几秒就改变系统的时间吗?!是的,如果您的操作系统不知道真正的绝对当前时间,PHP也无法帮助您。请注意,操作系统的时区不需要"正确",但必须理解绝对时间(再次参见其他答案)。
-
那么绝对时间是什么意思?操作系统如何知道它是什么?
-
@Flash阅读我发布的有关该主题的所有内容,此处以及您的其他问题。所有信息都在那里,您只需要处理和理解它。我知道这很令人困惑,但我不能在评论中总结它,而不是我已经提出的。
-
让我举个例子,为什么你不能说时间戳是独立的时区...当你超频一台电脑时,你有时会超频太多并且必须重置BIOS设置。然后,您以Y-m-d H:i:s格式设置系统时钟......这只是您设置的时间。当你在澳大利亚时,它会在同一时间点与美国不同。所以计算机并不真正知道它是什么。它取决于时区。这就是为什么我不明白为什么eveyone一直说时间戳是时区不依赖的。
-
@Flash UNIX时间戳与时区无关,因为世界各地的正确UNIX时间戳都是相同的。这是事实。你无法改变它。这是UNIX时间戳的定义。您将此问题与计算机如何正确计算UNIX时间戳相混淆。正如我已经解释的那样,这是操作系统的工作,它使用BIOS的时间+自己的时区设置+可能是NTP服务器到达正确的时间。如果系统的UNIX时间戳与另一个系统不同,则该系统的时间保持中断。
-
@Flash大多数计算机的BIOS在HH:MM:SS中保留时间而没有时区信息的事实是古代计算硬件的遗弃。将这个毫无价值的BIOS替换为将时间保留为UNIX时间戳的BIOS。这现在变得更清楚了吗?操作系统尝试补偿BIOS的有限能力,以尽可能保持绝对时间。例如,EFI BIOS提供了更好的时间管理:en.wikipedia.org/wiki/…
-
所以这是一个很大的问题,因为许多Android应用程序使用其中的虚拟化操作系统,并且它们具有固定的时区。例如Bit Web Server将时区固定为Asia/Jakarta ...因此在将时间戳写入数据库时??,它与实时无关。
-
@Flash如果时间戳以"HH:MM:SS"格式写入而不存储时区信息,那么是的,这是毫无价值的。如上所述,没有时区的"HH:MM:SS"基本上没有任何意义。一些数据库支持存储时间戳+时区(例如Postgres),这将解决该问题。总是存储雅加达时间甚至可能不正确,你只需要知道"HH:MM:SS"时间戳代表雅加达时间并对其进行适当处理。
-
没有看到BIOS让你选择时区或将时间设置为时间戳......:/
-
@Flash只要您拥有所需的所有信息,您就可以随时从当地时间获得绝对时间,反之亦然。对于当地时间你需要知道时区,否则它是没有价值的。
-
说实话,我确实理解这一切,但是想警告人们他们可能有问题。我不得不反编译该死的服务器以获取该信息,为什么时间戳保持错误。将它视为一个bug,但认为人们在创建应用程序时只是不在意。
-
@Flash所以你的一个特定服务器的计时被破坏了,而不是时区独立的UNIX时间戳。
Since PHP 5.1.0 (when the date/time functions were rewritten), every
call to a date/time function will generate a E_NOTICE if the timezone
isn't valid, and/or a E_WARNING message if using the system settings
or the TZ environment variable.
因此,为了获得UTC时间戳,您应该检查当前时区是什么,然后使用它还是只使用:
-
time()和strtotime(gmdate("M d Y H:i:s",time()))返回相同的结果: -
-
它们可能取决于您设置时区的方式,但并非总是如此。 有关其他说明,请参阅以下内容:us3.php.net/manual/en/function.gmdate.php
http://us3.php.net/time
"返回自Unix Epoch(1970年1月1日00:00:00 GMT)以来秒数测量的当前时间。"
所以我相信你的问题的答案是肯定的。
-
如何回答问题或问题?
-
重新检查标题。
-
是的,你是对的。抱歉。 +1而不是。
从文档中
Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT).
其中一条评论声称:"time()和strtotime(gmdate("M d Y H:i:s",time()))返回相同的结果"
由于我不确定,我进行了测试:
1 2 3
| $now = strtotime(gmdate("Y-m-d H:i:s", time()));
$now2 = time();
echo ' now='.$now.' now2='.$now2.' diff='.($now - $now2); |
产出是:
1
| now=1536824036 now2=1536806036 diff=18000 |
Diff是18000秒= 5小时=运行测试的服务器的时区偏移量。