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