如何在不依赖php.ini
或其他配置文件的情况下获取本地服务器的时区?
我正在寻找类似于date('e')
输出的输出。例如。 “UTC”,“GMT”或“Atlantic / Azores”。
我需要知道这一点,以便我可以知道MySQL时区。
答案 0 :(得分:9)
如果您使用的是基于Linux / Unix的托管平台,则可以将date命令的输出与“alphabetic time zone abbreviation”格式化程序一起使用:
$systemTimeZone = system('date +%Z');
但是,应该注意的是,您不一定要依赖系统的时区,而应该使用date_default_timezone_set(或date.timezone
php.ini设置)来设置所需的时区。
答案 1 :(得分:4)
如果您使用的是* nix,请使用popen
致电系统date
:
popen("date +%Z");
答案 2 :(得分:1)
在linux / unix上我使用
shell_exec("date +%Z");
答案 3 :(得分:0)
这些答案并不好。我不知道这是一种可移植的方法。
对于Linux,这里有一个选项:https://bojanz.wordpress.com/2014/03/11/detecting-the-system-timezone-php/
其他人列出的日期解决方案可能不准确,因为问题出在Linux中,而日期实用程序(gnuutils,gnulib)将继承相同的问题。
如果我将时区设置为欧洲/柏林,然后询问日期时区,它会给我CET。
在Linux中获取时区的方法如下:
#include <time.h>
#include <stdio.h>
extern char *tzname[2];
extern long timezone;
extern int daylight;
void main() {
tzset();
printf(tzname[0]);
}
问题是区域文件不包含其名称,只包括父时区列表或类似名称。
CET与欧洲/柏林地区不同。如果我把CET放入,那么日期可能会被错误地计算出来。有时候这并不重要,因为有些国家几十年来一直在使用一个时区,但有时它可能很重要。
在这里使用zdump是CET和欧洲/柏林之间的差异:
> Fri Mar 31 23:06:31 1893 UTC = Fri Mar 31 23:59:59 1893 LMT isdst=0 gmtoff=3208
> Fri Mar 31 23:06:32 1893 UTC = Sat Apr 1 00:06:32 1893 CET isdst=0 gmtoff=3600
< Sun Sep 16 00:59:59 1945 UTC = Sun Sep 16 02:59:59 1945 CEST isdst=1 gmtoff=7200
< Sun Sep 16 01:00:00 1945 UTC = Sun Sep 16 02:00:00 1945 CET isdst=0 gmtoff=3600
< Sun Apr 3 00:59:59 1977 UTC = Sun Apr 3 01:59:59 1977 CET isdst=0 gmtoff=3600
... SNIP about a dozen ...
< Sun Sep 30 01:00:00 1979 UTC = Sun Sep 30 02:00:00 1979 CET isdst=0 gmtoff=3600
> Wed May 23 23:59:59 1945 UTC = Thu May 24 01:59:59 1945 CEST isdst=1 gmtoff=7200
... SNIP couple dozen...
> Sun Oct 2 01:00:00 1949 UTC = Sun Oct 2 02:00:00 1949 CET isdst=0 gmtoff=3600
如果您使用unixtime,其中一些可能甚至不重要,但您可以清楚地看到,在70年代,有些人会这样做。可能还有一些其他时区的更新更新将会使用tzset的结果。对于许多人来说,这将是一个边缘问题,但如果它确实对你有影响,结果可能不会令人愉快。
我不知道Windows的约定是什么,或者是否存在同样的问题。这个问题有一个例外。如果您的系统时区是根区域(如GMT,UTC,CET等),那么我不认为应该发生此问题。
但是你的问题最终是关于MySQL的:
SELECT IF(@@global.time_zone = 'SYSTEM', @@global.system_time_zone, @@global.time_zone) AS time_zone;
如果设置为SYSTEM,它也将遭受与PHP和tzset相同的命运。我检查了一个朋友的服务器,并且经常有一个小时的差异,因为MySQL将欧洲/伦敦转换为GMT。 GMT不包括导致许多问题的BST。内部MySQL可能没问题,因为它仍然使用/ etc / localtime,即使MySQL报告了错误的名称,但是如果你使用了错误的名称并使用它来加载时区,那么它将指向正确的文件两者可能没有相同的时区。
即使您尝试包含DST,也不是一个完美的解决方案。如果你的MySQL实例正在使用SYSTEM,你可能想要看看你是否可以将日期转换为UTC(或PHP日期/时间),这可能会对性能造成痛苦。理论上你可以尝试暴力检测,但我不建议。您也可以尝试在会话变量中设置时区,MySQL可以自动转换,但要注意确保RTM(如果不能使用源代码)。
答案 4 :(得分:-1)
您实际上并不需要知道运行MySQL的“timezone” - 您只需要知道与 UTC 的区别。
要做到这一点你可以简单地问MySQL:
SELECT TIMESTAMPDIFF(HOUR, UTC_TIMESTAMP, NOW())
由于NOW()
的值基于MySQL运行的时区,因此将读取NOW()
与UTC时间之间的差异(以小时为单位)。然后,您可以使用该值创建2016-04-15T15:52:01+01:00
之类的完整时间戳,可以在DateTime::__construct()
中使用。
然后,您可以通过比较DateTime
个对象以及应在所有系统上工作,让PHP担心应用程序和数据库服务器之间的时区差异。
答案 5 :(得分:-1)
您可以通过此获取服务器的时区。 echo date_default_timezone_get();