Как я могу получить часовой пояс локального сервера? - PullRequest
12 голосов
/ 15 января 2011

Как я могу получить часовой пояс локального сервера, не полагаясь на php.ini или другие файлы конфигурации?

Я ищу вывод, похожий на вывод date('e').например.«UTC», «GMT» или «Атлантика / Азорские острова».

Мне нужно знать это, чтобы знать часовой пояс MySQL.

Ответы [ 6 ]

9 голосов
/ 15 января 2011

Если вы используете хостинговую платформу на основе Linux / Unix, вы можете использовать вывод команды date с форматером «буквенное сокращение часового пояса» следующим образом:

$systemTimeZone = system('date +%Z');

Однако следует отметить, что вам не обязательно полагаться на часовой пояс системы и что вместо этого следует использовать date_default_timezone_set (или параметр date.timezone php.ini), чтобы установить необходимый часовой пояс.

4 голосов
/ 15 января 2011

Если вы используете * nix, наберите date системы, используя popen:

popen("date +%Z");
1 голос
/ 25 августа 2015

В Linux / Unix я использую

shell_exec("date +%Z");
0 голосов
/ 13 февраля 2017

Эти ответы не очень хорошие. Я не знаю портативного способа сделать это.

Для 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. Для многих это было бы незначительной проблемой, но если это действительно повлияет на вас, результат, скорее всего, не будет приятным.

Я не знаю, что такое соглашение для окон или есть ли такая же проблема. Есть исключение из этой проблемы. Если ваш системный часовой пояс является корневым (например, 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 (если это не работает, используйте источник).

0 голосов
/ 16 декабря 2016

вы можете получить часовой пояс вашего сервера этим. echo date_default_timezone_get ();

0 голосов
/ 15 апреля 2016

На самом деле вам не нужно знать, на каком «часовом поясе» работает MySQL - вам просто нужно знать разницу с UTC .

Чтобы получить это, вы можете просто спросить MySQL:

SELECT TIMESTAMPDIFF(HOUR, UTC_TIMESTAMP, NOW())

Поскольку значение NOW() основано на часовом поясе, в котором работает MySQL, это будет считывать разницу между NOW() и временем UTC в часах. Затем вы можете использовать это значение для создания полной отметки времени, например 2016-04-15T15:52:01+01:00, которую можно использовать в DateTime::__construct().

Затем вы можете позволить PHP беспокоиться о разнице часовых поясов между сервером приложений и баз данных, сравнивая DateTime объекты ... и то, что должно работать на всех системах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...