如何获取本地服务器的时区?

时间:2011-01-15 14:41:03

标签: php date timezone

如何在不依赖php.ini或其他配置文件的情况下获取本地服务器的时区?

我正在寻找类似于date('e')输出的输出。例如。 “UTC”,“GMT”或“Atlantic / Azores”。

我需要知道这一点,以便我可以知道MySQL时区。

6 个答案:

答案 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();