Dater — определяет часовой пояс, локализует и форматирует дату-время в PHP

в 8:58, , рубрики: php, timezone, часовые пояса, метки: , ,

Dater — определяет часовой пояс, локализует и форматирует дату время в PHP

Когда при разработке веб-проекта встаёт задача учёта часовых поясов пользователей, то каждый раз решение как будто приходится изобретать заново. Из множества известных мне проектов решивших эту задачу я не припомню ни одного решения, которое можно было бы назвать простым, прозрачным для всей архитектуры и универсальным.

А что если хочется просто несколько строчек кода, и чтобы весь остальной код никогда не узнал, что данные клиенту нужно отдавать в другом часовом поясе, и что в данных пришедших от клиента время может быть указано с часовым поясом отличным от серверного? Для решения этой и многих других задач, сегодня я расскажу вам про одну лаконичную и функциональную библиотеку для PHP.

И так, встречайте — Dater, и его основные возможности:

  • Биндинг форматов
  • Локализация текстов и форматов
  • Расширение списка опций форматирования
  • Автоопределение часового пояса
  • Конвертация времени с учётом часового пояса
  • Автоматическая конвертация времени в $_GET, $_POST, $_REQUEST с учётом часового пояса
  • Автоматическая конвертация часового пояса в шаблоне отправляемых данных


Обещанные строчки кода по автоматическому определению и обработке пользовательского часового пояса оставим на десерт, а пока пробежимся по основным возможностям Dater, в кратце, на примерах.

Биндинг форматов

Позволяет стандартизовать для проекта набор используемых форматов и работать с ними по имени:

$dater->format(time(), 'd/m/Y'); // 2013/03/14
$dater->addFormat('slashedDate', 'd/m/Y');
$dater->format(time(), 'slashedDate'); // 2013/03/14
$dater->slashedDate(time()); // 2013/03/14

Расширение опций форматирования

Доступны все опции форматирования из date(), которые также могут быть переопределены и расширены:

$dater->addFormatOption('ago', function (DateTime $dateTime) {
    return floor((time() - $dateTime->getTimestamp()) / 86400) . ' days ago';
});
$dater->format(time() - 60*60*24*7, 'd F Y, ago'); // 14 March 2013, 7 days ago

Поддержка локалей

$dater->setLocale(new Dater_Locale_English());
echo $dater->date(); // 03/21/2013
echo $dater->now('j F Y'); // 21 March 2013

$dater->setLocale(new Dater_Locale_Russian());
echo $dater->date(); // 21.03.2013
echo $dater->now('j F Y'); // 21 марта 2013

Стандартные методы для серверных и пользовательских форматов с учётом локали

echo $dater->date(); // 03/21/2013 (depends on locale)
echo $dater->time(); // 5:41 AM (depends on locale)
echo $dater->datetime(); // 03/21/2013 5:41 (depends on locale)
echo $dater->serverDate(); // 2013-03-21
echo $dater->serverTime(); // 09:41:28
echo $dater->serverDateTime(); // 2013-03-21 09:41:28
echo $dater->clientDate(); // 2013-03-21
echo $dater->clientTime(); // 05:41:28
echo $dater->clientDateTime(); // 2013-03-21 05:41:28

Конвертация даты-времени с учётом часового пояса

$dater->setServerTimezone('Europe/Moscow');
$dater->setClientTimezone('Europe/London');
echo $dater->serverDateTime(); // 2013-03-21 08:18:06
echo $dater->clientDateTime(); // 2013-03-21 04:18:06
echo $dater->time(); // 04:18

Стоит упомянуть, что при вызове $dater->setServerTimezone('Europe/Moscow'); функция date() и класс DateTime будут возвращать время в новом установленном часовом поясе. Чтобы это отключить передайте методу false вторым параметром.

И наконец обещанное

Код, который позволит вам автоматически определить часовой пояс клиента и выводить для него актуальную дату-время:

В заголовке глобального скрипта инициализации

$dater = new Dater(new Dater_Locale_Russian(), 'Europe/Moscow');
$timezoneDetector = new Dater_TimezoneDetector();
$dater->setClientTimezone($timezoneDetector->getClientTimezone())

$dataHandler = new Dater_DataHandler($dater);
$dataHandler->enableOutputTimezoneHandler();
$dataHandler->convertRequestDataToServerTimezone();

В основном шаблоне

<html>
	<head>
		<?= $timezoneDetector->getHtmlJsCode() ?>
	</head>
</html>

Теперь все строки YYYY-MM-DD HH:MM:SS в отправляемых данных будут заменены на YYYY-MM-DD HH:MM:SS в автоматически определённом часовом поясе клиента. Если же вам нужно выводить дату-время в определённом формате, то достаточно добавить YYYY-MM-DD HH:MM:SS[Н m d] или YYYY-MM-DD HH:MM:SS[date] где date — забинденный в Dater формат. Также можно выводить и форматировать timestamp формат: 1363853607[d.m.Y].

Например, следующие данные:

<html>
<body>
	Timestamp format: 1363238564 (не изменится)
	Timestamp format: 1363238564[Y/m/d]
	Timestamp format: 1363238564[datetime]
	Server datetime format: 2013-03-14 09:22:44[Y/m/d]
	Server datetime format: 2013-03-14 09:22:44[time]
	Server datetime format: 2013-03-14 09:22:44
</body>
</html>

Будут автоматически конвертированы в:

<html>
<body>
	Timestamp format: 1363238564 (не изменится)
	Timestamp format: 2013/03/14
	Timestamp format: 14.03.2013 07:22
	Server datetime format: 2013/03/14
	Server datetime format: 07:22
	Server datetime format: 2013-03-14 07:22:44
</body>
</html>

В то же время $dataHandler->convertRequestDataToServerTimezone(); сделает так, что все YYYY-MM-DD HH:MM:SS данные поступающие от клиента будут конвертированы в YYYY-MM-DD HH:MM:SS часового пояса сервера. Таким образом сервер никогда не узнает о том, что клиента работает получает и отправляет дату-время в другом часовом поясе.

Стоит признать, что это немножко экстримальный вариант обработки часовых поясов. Более универсальным и традиционным решением было бы отказаться от использования $dataHandler->enableOutputTimezoneHandler(); и просто обрамлять вставку каждой даты-времени вызовом соответствующего метода форматирования. Например <?= $dater->date($dateTimeOrTimestamp) ?>.

О проекте

Честно признаюсь, что являюсь автором этой библиотеки, и буду очень благодарен за любую критику и помощь в доработке. Исходники выложены на GitHub под свободной BSD лицензией, пользуйтесь и распространяйте как пожелаете.

Надеюсь кому-нибудь таки пригодится :)

Автор: liaren

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js