Как я могу получить часовой пояс локального сервера, не полагаясь на php.ini
или другие файлы конфигурации?
Я ищу выход, похожий на вывод date('e')
. например. «UTC», «GMT» или «Atlantic / Azores».
Мне нужно знать это, чтобы я мог узнать часовой пояс MySQL.
Если вы используете платформу хостинга на базе Linux / Unix, вы можете использовать вывод команды date с форматом «алфавитный временной пояс» как таковой:
$systemTimeZone = system('date +%Z');
Однако следует отметить, что вам не обязательно полагаться на часовой пояс системы, и вместо этого вы должны использовать date_default_timezone_set (или параметр date.timezone
php.ini), чтобы установить требуемый часовой пояс.
Если вы находитесь на * nix, вызовите date
системы, используя popen
:
popen("date +%Z");
В linux / unix я использую
shell_exec("date +%Z");
Эти ответы не очень хорошие. Я не знаю, как это сделать.
Для Linux здесь один вариант: https://bojanz.wordpress.com/2014/03/11/detecting-the-system-timezone-php/
Другие решения для определения даты могут быть неточными, так как проблема связана с Linux, а утилита date (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 и Europe / Berlin:
> 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 (если это не работает с источником).
Вам не нужно знать, на какой «часовой пояс» работает MySQL, вам просто нужно знать разницу в UTC .
Чтобы получить это, вы можете просто спросить MySQL:
SELECT TIMESTAMPDIFF(HOUR, UTC_TIMESTAMP, NOW())
Поскольку значение NOW()
основано на часовом поясе MySQL, который будет читать разницу между NOW()
и временем UTC, в часах. Затем вы можете использовать это значение для создания полной метки времени, например 2016-04-15T15:52:01+01:00
которая может использоваться в DateTime::__construct()
.
Затем вы можете позволить PHP беспокоиться о различиях в часовых поясах между серверами приложений и баз данных, сравнивая объекты DateTime
… и это должно работать на всех системах.
вы можете получить часовой пояс своего сервера. echo date_default_timezone_get ();