我正在编写一个CLI PHP脚本,我希望它显示的日志消息包含正确的本地时间。
此脚本将包含在小型软件版本中,并作为配置步骤的一部分在不同的计算机(在 Linux 上)上运行。我只需要时间来正确标记日志消息,系统的其他部分都不需要当前时间信息,而且我对 PHP 的使用是一个实现细节,所以我觉得要求用户(可能只是为了运行这个而安装 PHP)编辑脚本或摆弄他们的 PHP 安装来设置date.timezone
是不合理的。
我说以上是鉴于以下事实...
python -c 'import datetime; print datetime.datetime.now()'
ruby -e 'print Time.now, "n"'
perl -MPOSIX -le 'print strftime "%F %T", localtime $^T'
awk 'BEGIN { print strftime("%F %T", systime()) }'
date
。都正确地意识到,现在还不到凌晨4点,但实际上只是下午三点半
。最初 Node.js 似乎处于同一个顽固的 UTC 阵营,但似乎有一些库能够自动检测当前时区并应用它。我不知道PHP有任何类似的东西。
不幸的是,根据 https://bojanz.wordpress.com/2014/03/11/detecting-the-system-timezone-php/的说法,PHP 早在 2012 年就停止在 5.4 版本中查看系统对时区的想法。
我不完全明白为什么 PHP 决定认输并诉诸"用户硬编码或破产",而我刚刚测试的其他 4 种主要编程语言运行良好。
话虽如此,我相信有一个正当的理由,我非常想读一读。
在我的(Slackware)系统上,TZ未设置,但/etc/localtime
是我的时区文件的副本。请注意,它不是符号链接,因此上述链接中指出的readlink()
解决方法与我无关。
我一再想知道实际打开和解析我的本地时间文件会有多复杂。
DateTime 和各种日期函数不提供解析任意 tzinfo 文件的方法。
strace
ing PHP 显示它在启动时打开并读取/etc/localtime
,但令人沮丧的是,该语言不会以任何方式公开加载的数据。
我找不到这个问题的任何重复项,但是如果没有,我会感到非常惊讶,因为在撰写本文时,这可以说是一个开放的问题不到 6 年。
通常,您希望在 php 中设置时区.ini具体取决于您的应用程序要求,但我知道对于您将手动使用的 CLI 工具而不是 cron 作业,您可能希望使用系统时区。你可以试试这个:
$ret = null;
$output = null;
exec('date +%Z', $output, $ret);
if ($ret)
{
throw new Exception("Failed to get system timezone");
}
$timezone = $output[0];
然后,您可以在脚本中将其设置为默认时区:
date_default_timezone_set($timezone);