Система с множеством таймзон

Koc

Новичок
Имеется:
1. база проекта, все даты в ней за редким исключением - MySQL DATETIME, Europe/Moscow (server setting). Исключение - пара таблиц в MySQL DATETIME Utc
2. пользователи, у которых в настройках указана таймзона
3. Symfony2, Doctrine2.

Что нужно:
4. большинство контента выводится относительно таймзоны пользователя
5. некоторый контент выводится относительно той территории, к которой привязан


Конвертировать старые даты в Utc - ваще не вариант. Потратим уйму времени.
Ну допустим я добавил 2 новых типа данных в доктрину - datetime_utc, datetime_moscow. При занесении в базу/гидрации строки будет указана корректная дата. Перед форматированием и выводом даты я должен применить таймзону пользователя или города. В этом-то и напряг.

Дата форматируется в тысяче мест: как в шаблонах так и в контроллерах с репозиториями. Соответственно я должен пробежаться везде и поставить вызов какого-то своего хелпера, который применит нужную таймзону. Проблемы собственно 2:
1. вот так глобально везде это все поменять
2. добавление зависимости от хелпера


PHP:
<?php
// например есть
MeetRepository::getPastMeets($limit, $skip)
{
    return $this->createQueryBuilder('m')->where('m.startAt >= :date')->setParameter('date', new DateTime())->getResult();
}

// так вот, теперь я должен принудительно проставить тип данных
MeetRepository::getPastMeets($limit, $skip)
{
    return $this->createQueryBuilder('m')->where('m.startAt >= :date')->setParameter('date', new DateTime(), 'datetime_moscow')->getResult();
}

// но это ерунда, по сравнению с тем, что я должен указать таймзону, в которой нужно создавать DT
MeetRepository::getPastMeets($limit, $skip)
{
    return $this->createQueryBuilder('m')->where('m.startAt >= :date')->setParameter('date', new DateTime('now', USER_TIMEZONE), 'datetime_moscow')->getResult();
}
Как быть?
 

AmdY

Пью пиво
Команда форума
Немного оффтопа близкого к теме.
Всё время нужно хранить в UTC, выводиться с учётом его настроек, пользователь может сменить таймзону и тогда если не utc задалбёшь пересчитывать. В то же время возникают проблемы с шудлером, если он работает по принципу крона и нужно выполнять задание по понедельникам и средам. Но это проблема программирования шудлеров. Да и NOW() базы данных лучше не использовать а цепляться за одно время получаемое в php.

Теперь по твоему вопросу, ты его решаешь не с той стороны, его лучше решать через кустомный тип поля, http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#custom-mapping-types или на крайний случай через Template c beforeDql или как его там.

Когда проверял теорию с шаблонами наткнулся на нужный тебе пункт http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/working-with-datetime.html
 

Koc

Новичок
Всё время нужно хранить в UTC
да, новые таблицы так и сделаны. Но переделывать старые - желания/времени нет. Поэтому мы пришли к соглашению, что в качестве UTC там выступает Europe/Moscow. Когда мы извлекаем из базы строку, то $entity->getCreatedAt() вернет instanceof DateTime, Europe/Moscow а не абы что (не обязательно date_default_timezone_get()).

Да и NOW() базы данных лучше не использовать а цепляться за одно время получаемое в php.
так и делаем, но тут все равно проблемы, описанные выше

Так есть кастомный тип поля - datetime_utc, datetime_moscow. Извлекли мы дату из базы, у нас это допустим UTC, теперь нужно этой дате установить пользовательскую таймзону - вот и зависимость.
 

Koc

Новичок
ого, а есть предпосылки к этому?

ну даже если и вернут - менять в одном месте только нужно будет - в обработчике типа datatime_moscow
 
Сверху