Работа с временными зонами в PHP
Как только проект перестает быть завязан на ограниченное количество потребителей и растет география его применения, встает вопрос о применении временных зон. Когда я работал в одной известной интернет компании внедрение в работу временных зон (как в интерфейс отображения статистики, так и в программу анализа) было достаточно серьезным шагом.
Проблемы временных зон
- Большинство мест на земле имеют часовое смещение
- Некоторые места имеют получасовое или пятнадцати-минутное временное смещение
- В некоторых местах временная зона меняется в течении года
Проблемы перевода времени
- Множество стран переводит время дабы увеличить продолжительность светлой части суток
- Это делают не во всех странах
- Перевод часов происходит в разное время
- Существует большое количество исключений
Другие проблемы временных зон и «перевода стрелок»
- В Австралии зоны строго вертикальные
- В Бразилии дата, когда переводят срелки, меняется каждый год
- На остров Lord Howe (Австралия) переводят стрелки только на почаса
- Непал переводит стрелки на 15 минут
Проблемы в наименовании временных зон
- Одно именование может означать разные временные зоны:
Например:PST — Pacific Standart Time и Pakistan Standart Time
EST — Easten Standart Time (США), Easten Standart Time (Австралия) и Easten Brazil Standart Time - Одна зона может иметь несколько наименований
Более того, в разных операционных системах имена зон могут различаться.
Проблемы в представлении даты и времени
- Двусмысленность
06/08/04
6 Августа 2004 года
8 Июня 2004 года
4 Августа 2006 - Нечитаемость
20040425010541
25 Апреля 2004 года 01:05:41 - Другие «магические» форматы
third saturday
2004-03-10 16:33:17.11403+1
2001-11-29T13:20:01.123-05:00
23:41:00.0Z
04:05:07.789 +0930
1999.238
Функции в php 4 и php 5 для работы с временем и датами
- checkdate — Проверяет правильность даты по грегорианскому календарю
- date(gmdate) — Форматирует системную дату/время (по Гринвичу)
- getdate — Возвращает информацию о дате/времени
- gettimeofday — Возвращает текущее время
- localtime — Возвращает системное время
- mktime(gmmktime) — Возвращает метку времени для заданной даты (по Гринвичу)
- strftime(gmstrftime) — Форматирует дату/время с учетом текущей локали (по Гринвичу)
- strtotime — Преобразует текстовое представление даты на английском языке в метку времени Unix
Ограничения работы с датами
- Использование Unix-таймстампа в качестве базы (количество секунд, прошедшее с 1 января 1970 года по Гринвичу)
- Таймстамп представляется ввиде 32-битного целого, что ограничивает использование данного представления диапазоном 1902-2038 годами
- На многих операционных системах данный тип может быть только положительным, ограничение диапазона 1970-2038
- strtotime — достачно сложная функция, реализация которой подвержена большим количеством ошибок
- Нет вариантов корректной работы с временными зонами
- Некоторые функции являются зависимыми от операционной системы
Улучшения работы с датами в php 5.1 и выше
- Использование 64-битного типа для хранения даты. Теперь граница интервала использования данного типа 4 Декабря 292277026596 год
- Функция strtorime была переписана
- Больше нет зависимости в реализации от операционной системы
- Полная поддержка временных зон, перевода часов и модификаторов дат
- Новый формат модификаторов временных зон
- Более продвинутые функции для работы с датами
Форматы данных в php 5.1 и выше
Американский формат: 9/11;4:08 pm;12/22/78; 8:51:00 am
Комбинированный формат: Sat, 24 Apr 2004 21:48:40 +0200; 2001-11-29T13:20:01.123-05:00
Описательный формат: tomorrow; four months ago; last saturday; +20 days 2 hours
Текстовый формат: December 22. 1978; 22-december-1978
Все ISO 8601 форматы: 1978/12/22; 13:03:12.45678; 13:03:12.45678 +0100; 15:57-8; 1978-12-22; 15:57:41 pdt; 13:03:12.45678 CEST; 231431 CEST; 70-4-25; 13:03 CEST; 04:05 -0930; 23:41F
Форматы баз данных: 1999-Jan-08; 1999.238
Поддержка временных зон в php 5.1 и выше
- Встроенная база на 551 временную зону
- Нет зависимости от аббревиатуры временной зоны
- Названия временных зон имеют формат — Continent/Location или Continent/Location/Sublocation
Поддержка временных зон. Как использовать?
- Каждая временная зона идентифицируется городом с наибольшим населением на данной территории
- Зоны разделены на 10 больших групп: Африка, Америка, Антарктика, Арктика, Азия, Европа, Индия, Тихий океан
- Существует также группа Другие, состоящая из вышедших из употребления названий и служащая для обеспечения обратной совместимости
- Больше информации по аббревиатурам временных зон по указанному адресу
Изменение информации по временным зонам
- Обновления информации по временным зонам происходят около 20 раз в год
- Большинство обновлений происходят неожиданно
- Чтобы не потерять актуальность, релизы php должны быть достаточно часты
- Расширение pecl, которое исправляет данные недостатки, называется timezonedb (pecl install timezonedb)
Разбор дат (прошлое)
Разбор строки с информации о дате и времени используя функцию strtotime
$date=strtotime(«2005-07-11 22:16:50 CEST»);
$ts=strtotime(«next week»,$date);
date_default_timezone_set(«Europe/Oslo»);
$ts=date_create(«1979-12-31 09:15»);
echo date_format($ts,«D Y-m-d H:i:s -\I\S\O \W/\Y: W/o»);
date_default_timezone_set(«Europe/Oslo»);
$ts=date_create(«December 22nd, 2005 15:41»);
echo date_format($ts, DATE_ISO8601);
echo date_format($ts, DateTime::RFC1036);
echo date_format($ts, DATE_RSS);
date_default_timezone_set(«Europe/Oslo»);
$ts=date_create(«December 22nd, 2005 15:41»);
$locales=array(‘en_US’,’fr_CA’,’nb_NO’,’ru_RU’,’ar_SA’,’ja_JP’);
foreach($locales as $locale)
<
locale_set_default($locale);
echo date_format_locale($ts,DATE_RFC2822).»\n»;
>
$date=new DateTime(‘now’);
echo $date->format(DateTime::ISO8601).»\n»;
$date->setTime(15,0,7);
echo $date->format(DateTime::ISO8601).»\n»;
$date->setDate(2006,12,22);
echo $date->format(DateTime::ISO8601).»\n»;
$date->setIsoDate(2006,45,2);
echo $date->format(DateTime::ISO8601).»\n»;
date_default_timezone_set(«Europe/Oslo»);
$date=new DateTime(‘now’);
echo $ts->format(DATE_RFC2822).»\n»;
$ts->modify(«+2 days»);
echo $ts->format(DATE_RFC2822).»\n»;
$ts->modify(«fifth month»);
echo $ts->format(DATE_RFC2822).»\n»;
$ts->modify(«Friday +3 weeks»);
echo $ts->format(DATE_RFC2822).»\n»;
$ts->modify(«next friday»);
echo $ts->format(DATE_RFC2822).»\n»;
date_default_timezone_set(«Europe/Oslo»);
$ts=date_create(«1978-12-22 09:15»);
echo $ts->format(‘e’);
$tz=new DateTimeZone(‘Pacific/Honolulu’);
$ts1=new DateTime(‘1978-12-22 09:15 CEST’,$tz);
$ts2=new DateTime(‘1978-12-22 09:15 Europe/Amsterdam’,$tz);
echo $ts2->format(DateTime::RFC2822);
$tz=timezone_open(‘Asia/Singapore’);
echo timezone_name_get($tz);
$tz=timezone_open(‘CEST’);
echo timezone_name_get($tz);
$tz=new DateTimeZone(»Europe/Amsterdam»);
$d=new DateTime(«2005-01-22 09:15»);
echo $tz->getOffset($d);
$d->modify(«+6 months»);
echo $tz->getOffset($d);
$tz1=timezone_open(‘Pacisic/Honolulu’);
$tz2=timezone_open(‘Europe/Amsterdam’);
$tz3=timezone_open(‘Australia/Melbourne’);
$ts=date_create(«1978-12-22 09:15»,$tz1);
echo $ts->getTimezone()->getName().’:’.$ts->format(DATE_RFC822).»\n»;
$ts->setTimezone($tz2);
echo $ts->getTimezone()->getName().’:’.$ts->format(DATE_RFC822).»\n»;
$ts->setTimezone($tz3);
echo $ts->getTimezone()->getName().’:’.$ts->format(DATE_RFC822).»\n»;
$tz=timezone_open(‘Europe/Amsterdam’);
$trs=timezone_transitions_get($tz); // или $trs=$tz->getTransitions();
foreach($trs as $ts)
printf(«%20s %7d %d %s\n»,$tr[‘time’],$tr[‘offset’],$tr[‘isdst’],$tr[‘abbr’]);
$ids = timezone_identifiers_list();
echo «Number of identifiers: ».count($ids).»\n»;
echo implode(«, «, array_slice($ids, 0, 5)).’. ‘.implode(«, «, array_slice($ids, -5));
$abbrs = timezone_abbreviations_list();
foreach ($abbrs as $abbr => $ids)
foreach ($ids as $id)
printf(«%-6s %6d %d %s\n», strtoupper($abbr),$id[‘offset’],$id[‘dst’], $id[‘timezone_id’]);
date_default_timezone_set(«America/New_york»);
$tz = new DateTimeZone(«America/New_york»);
foreach (timezone_transitions_get($tz) as $tr)
if ($tr[‘ts’] > time()) break;
$d = new DateTime( «@<$tr['ts']>» );
printf(«The timezone %s switches to %s on %s.\nThe new GMT offset will be: %d (%s)\n», $tz->getName(), $tr[‘isdst’]? «DST»: «standard time», $d->format(‘d M Y @ H:i T’), $tr[‘offset’], $tr[‘abbr’]);
Когда появится данная функциональность
В php 5.1 необходимо скомпилировать, используя флаг CFLAGS=-DEXPERIMENTAL_DATE_SUPPORT=1
В php 5.2 и выше по умолчанию
Источник
apache — установка date.timezone в php.ini не работает
Снимок вывода функции phpinfo ():
Поскольку я пытаюсь установить Roundcube, для которого требуется установить date.timezone, я хотел бы установить date.timezone, заполнив поле date.timezone в php.ini.
Конфигурация сервера
- Debian 9 (Stretch)
- PHP 7.0.19-1 (cli) (построено: 11 мая 2017 года, 14:04:47) (NTS)
- Apache / 2.4.25 (Debian)
Что я пробовал
В соответствии с http://php.net/manual/en/timezones.php , Я изменил поле date.timezone в /etc/php/7.0/apache2/php.ini и /etc/php/7.0/cli/php.ini с разными синтаксисами:
И я всегда перезагружал Apache после любого изменения.
Ничего не изменилось в phpinfo, поле date.timezone всегда установлено на «no value», и на первом шаге установки Roundcube date.timezone НЕ в порядке.
Но когда я пытаюсь:
Я прочитал много довольно старых постов об этом типе проблемы, но различные решения не работали для меня. Любая идея?
РЕДАКТИРОВАТЬ
Путь к файлу конфигурации (php.ini)
Загруженный файл конфигурации
Просканируйте этот каталог на наличие дополнительных файлов .ini.
Проанализированы дополнительные файлы .ini
Источник
Настройка PHP timezone в php.ini
Во время работы с Symfony framework получил следующее предупреждение (warning):
На самом деле, ничего страшного или необычного — это было вызвано обновлением PHP до версии 5.4, а так как новая версия стала рядом со старой с новыми конфигами, пришлось заново настроить PHP timezone в php.ini. Для начала, нужно узнать, в какой мы timezone. Точнее, как ее нужно указать в PHP конфиге. Сделать это можно здесь: http://www.php.net/manual/ru/timezones.europe.php
Открываем файл php.ini. У Debian это делается так:
С помощью поиска ищем ;date.timezone (если такой строки нету — тогда добавляем сами). Видим, что строка закомментирована:
Раскомментируем ее и ставим локаль, например:
Сохраняем файл. Так же это можно сделать у самом php-скрипте или .htaccess файле (например, на если на шаред хостинге — нельзя править php.ini). В первом случае достаточно написать в скрипте
Этот способ также подходит, если вы хотели сделать юзеру приятное и отображать время в зависимости от его расположения.
Во втором случае, дописываем в .htaccess (если только php не в режиме fastcgi)
Чтобы изменения вступили в силу, необходимо перегрузить конфигурацию apache. Или перезапустить полностью. У Debian, SysVinit:
Этот способ так же работает у php 5.5, 5.6 и 7.*.
Источник
Невозможно установить дату.часовой пояс в php.ini-файл
Я использую php5.5 и получение этой ошибки всякий раз, когда я использовал функцию даты в PHP:
загруженный файл конфигурации находится здесь:
поэтому я изменил дату.установка часового пояса в это:
затем я перезапускаю сервер:
но все равно получаю эту ошибку, я попытался проверить .ini-файл в дополнительном расположении ini-файла, но ни один из них не переопределяет дату.настройка часового пояса
Я проверил php.разрешение ini-файла, но все еще не работает пожалуйста, направьте меня, чтобы решить эту проблему, спасибо..
11 ответов
давайте найдем правильный php.ini. Запустите это в apache / nginx / любом веб-сервере, который вы используете (потому что версия командной строки может отличаться от используемой ею).
чем .ini на выходе? Все тот же?
после php.ini edit, просто перезапустите веб-сервер (apache или nginx).
наконец-то решил мою проблему, это мой загруженный файл конфигурации:
изменена дата.часовой пояс здесь, но он не работает.
Итак, я проверяю » сканировать этот dir для дополнительного .ini-файлы » значения в phpinfo (), которые указывают на:
затем я ищу дату.часовой пояс у всех файлов в этой папке, но не нашел.
Это мой дополнительный .ini-файл проанализировал значение в phpinfo ():
Я изменил файл /etc/php5 с/apache2 не/конф.d / 20-xdebug.ini, и добавил эту строку:
очень странно, но это решило мою проблему .
вы должны проверить, найдите php.в, если где-то есть еще один.
для меня. там должен быть CLI для интерфейса командной строки:
это работает для меня сейчас.
другим решением для меня после компиляции PHP из исходного кода было проверить php.ini фактически загружал файл конфигурации. Из командной строки
перезапустить PHP (в моем случае /etc/init.d/php-fpm stop , /etc/init.d/php-fpm start ) и он отлично работает. По какой-то причине он был скопирован неправильно.
- Дистрибутив: Centos 7
- Веб-Сервер: Nginx
- тип: экземпляр EC2
недавно я столкнулся с той же проблемой с PHP 5.6.4.
- в PHP 5.6.4 ведет себя странно
- в PHP 5.6.11 ведет себя нормально, как и ожидалось
когда я ставлю date.timezone опция конфигурации в разделе [PHP] в файле конфигурации отлично работает для PHP 5.6.4. Например я добавил опцию в самом начале
но когда я поставил настройки, как это показано в Примере под [Date] раздел он работает не так, как ожидалось, похоже, что опция игнорируется
когда я добавляю опцию в 20-xdebug.ini как это предложение в принятом ответе https://stackoverflow.com/a/20731466/2111430 опция принята, потому что этот файл имеет только . Из любопытства я попробовал другие ini файлы и, похоже, я могу использовать любой.
еще раз, проблема произошла для меня только с PHP 5.6.4. Когда я изменил опцию на сервере с PHP 5.6.11, она вела себя точно так, как я ожидал.
проверьте наличие конфликтующих настроек в php.ini, у меня была такая же проблема, и в моем случае настройки xdebug определены до даты.часовой пояс, вызывающий эту вещь: для более подробной информации см.:PHP Xdebug issue — дата.часовой пояс и сеанс.save_path undefined
Он работал для меня, когда я заметил, что дата.запись часового пояса в PHP.ini был прокомментирован. После удаления точки с запятой часовой пояс был установлен правильно.
некоторые установщики приложений php командной строки (например, установщик symfony или даже когда PHP-скрипты запускаются из cli) используют ini-файл внутри каталога php-cli
это решило мою аналогичную проблему в процессе проверки зависимостей при установке Symfony.
я исправил это в Mac OSX El Captain, создав структуру папок: / Library/Server/Web/Config / php, а затем создав php.ini внутри этой новой папки php только с датой.директива часового пояса.
Если вы установили дату.значение часового пояса в PHP.ini но он не работает (т. е.. локальное значение и основное значение разные), то вам может потребоваться обновить что-то вроде этого в файле конфигурации apache:
в моем случае у меня было 2 date.timezone= записи в php.ini-файл и последний был переопределен первым. удаление одного из них решило мою проблему.
также не забывайте, что вам нужно перезапустить процесс веб-сервера.
Источник