Задать вопрос
@AlexKuznec

Как в Yii2 узнать часовой пояс пользователя?

Использую в Yii2 DateTimePicker для выбора пользователем даты/времени.
По умолчанию Yii2 считает, что все полученное время в поясе UTC.
DateTimePicker при нажатии на кнопку "Сегодня" выбирает текущее локальное время и передает в базу, где оно воспринимается как UTC.

Я решил хранить в таблице сразу 2 поля с указанным временем:
time - int(11) - timestamp события в UTC (для вычислений)
usertime - datetime - запись локального времени, чтобы пользователь видел то же самое время, которое он сохранял, даже находясь в другом часовом поясе (например, в отпуске)

Вопрос: как узнать часовой пояс пользователя, или хотя бы разницу времени между UTC и временем пользователя?

Почему-то встроенных решений не нашел. Только одну библиотечку dater/dater, которая не связана с Yii2 и сильно дублирует функционал Formatter, но имеет средство $timezoneDetector->getHtmlJsCode() которая через JavaScript какими-то хитрыми вычислениями определяет часовой пояс. Но по ощущению тот еще костыль.
В большинстве обсуждений предлагается TimeZone определять чуть ли не самостоятельно прописывая вычисления на JavaScript исходя из времени пользователя (тут можно багов наделать и долго отлаживать). Еще вариант определять географическое положение по IP.

Есть ли какие-то способы средствами Yii2? Ведь он поддерживает часовые пояса и форматтер умеет разбирать время с указанием часового пояса, из документации:
Yii::$app->formatter->asTime('2014-10-06 14:41:00 CEST');
А вот виджетов, которые умеют цеплять к передаваемым данным указание часового пояса, я не нашел.
  • Вопрос задан
  • 2131 просмотр
Подписаться 2 Оценить 1 комментарий
Решения вопроса 1
@AlexKuznec Автор вопроса
В общем, на данный момент нашел 2 более-менее готовых решения:

1) Геолокация по IP.
Плюсы: реализовано для Yii2, можно узнать страну, регион и город пользователя, что кроме часового пояса дает нам информацию о предполагаемом языке и валюте пользователя. Хотя, браузеры собирают языковые предпочтения пользователя, так что при их наличии лучше использовать их.
Минусы: сложность системы, не гарантирует верный результат, есть небольшая плата при высоких нагрузках (легко окупится рекламой на сайте).
https://github.com/marciocamello/yii2-sypexgeo/

2) Определение часового пояса через JavaScript на стороне клиента.
Плюсы: просто, бесплатно.
Минусы: не найдено реализаций для Yii2, работает только при корректных настройках времени у пользователя и актуальной базы данных о часовых поясах (у меня, к примеру, для Барнаула отображаются устаревшие данные).

Я взял вот эту библиотечку:
https://github.com/barbushin/dater

и встроил в Yii2 следующим образом (если предложите вариант получше - буду благодарен):
в конфигурации:
'components' => [
'timezoneDetector' => [
'class' => 'Dater\TimezoneDetector',
]
],

'on ' . yii\base\Application::EVENT_BEFORE_REQUEST => function ($event) {
$clientTimezone = Yii::$app->timezoneDetector->getClientTimezone(); // часовой пояс пользователя
if (isset($clientTimezone)) Yii::$app->timeZone = $clientTimezone;
},

и в шаблоне layouts/main.php
< head>
...
<?= Yii::$app->timezoneDetector->getHtmlJsCode() // определение часового пояса пользователя ?>
...
< /head>

вставка в шаблон приложения дополнительного кода мне не нравится, так как хотел написать поведение для Yii2, но следующий код у меня работать не стал (пробовал на разные события цеплять)
'on ' . yii\base\Application::EVENT_AFTER_REQUEST => function ($event) {
Yii::$app->view->registerJs(Yii::$app->timezoneDetector->getHtmlJsCode(), yii\web\View::POS_HEAD);
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@dmirogin
Почему-то встроенных решений не нашел. Только одну библиотечку dater/dater, которая не связана с Yii2 и сильно дублирует функционал Formatter, но имеет средство $timezoneDetector->getHtmlJsCode() которая через JavaScript какими-то хитрыми вычислениями определяет часовой пояс. Но по ощущению тот еще костыль.
В большинстве обсуждений предлагается TimeZone определять чуть ли не самостоятельно прописывая вычисления на JavaScript исходя из времени пользователя (тут можно багов наделать и долго отлаживать). Еще вариант определять географическое положение по IP.


Да, только так.
На сервере вы можете получить только таймзону сервера.
Ответ написан
Комментировать
webinar
@webinar Куратор тега Yii
Учим yii: https://youtu.be/-WRMlGHLgRg
Для получения timezone пользователя использовать js и передавать на сервер.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы