2

I store in my database dates most of the time with DateTime on MySQL on UTC time. I'm using Symfony 2.4.5 (yes it is old).

I retrieve dates from the controller with normal sql query from Propel. Since I do not want to query the user timezone all the time from the database I will save in the session the user's timezone '{'timezone'=> 'Europe/Paris'}.

Should I convert the dates retrieved from DB in the controller or do that in Twig ?

// In controller
$dictionaryThatHaveOtherData = ...
$dateFromDbInUTC = UserQuery::Create()->...
$dateFromDbInUTC->setTimeZone(new DateTimeZone($this->get('session')->get('timezone')));
$dictionaryThatHaveOtherData['dateForSomething'] = $dateFromDbInUTC;
// In Twig
{{ dateForSomething | date('theFormatIWant') }}

Or instead do the convert in Twig:

// In controller
$dictionaryThatHaveOtherData = ...
$dateFromDbInUTC = UserQuery::Create()->...    
$dictionaryThatHaveOtherData['dateForSomething'] = $dateFromDbInUTC;
// In Twig
{{ dateForSomething | date('theFormatIWant', app.session.timezone) }}

I guess it is better to do in controller as the view shall only care about showing data in desired format and not involves to many things like thinking about if the date is already in good timezone or not.

What about if the view needs to do comparisons between dates, would it be better in UTC or user timezone ? Does it make a difference ?


EDIT since answer from DarkBee:

First I tried in twig view:

  • date('H:i:s', user_timezone.zone)
  • date('H:i:s', app.session.get('timezone'))
  • date('H:i:s')
  • date('H:i:s', 'Europe/Paris')
  • date('H:i:s', 'Asia/Shanghai')
  • date('H:i:s', false)

    Send to view with UTC timezone

  • 19:00:00

  • 19:00:00
  • 11:00:00
  • 13:00:00
  • 19:00:00
  • 11:00:00

    Send to view with Shanghai timezone

  • 19:00:00

  • 19:00:00
  • 11:00:00
  • 13:00:00
  • 19:00:00
  • 19:00:00

    In controller : $this->get('Twig')->getExtension('core')->setTimezone('Europe/Paris');

  • 19:00:00

  • 19:00:00
  • 13:00:00
  • 13:00:00
  • 19:00:00
  • 11:00:00

    In controller: $this->get('Twig')->getExtension('core')->setTimezone($this->get('session')->get('timezone'));

  • 19:00:00

  • 19:00:00
  • 19:00:00
  • 13:00:00
  • 19:00:00
  • 11:00:00

    In controller and date with shanghai timezone : $this->get('Twig')->getExtension('core')->setTimezone('Europe/Paris');

  • 19:00:00

  • 19:00:00
  • 13:00:00
  • 13:00:00
  • 19:00:00
  • 19:00:00

So yes we see that 'date('H:i:s')' is the good time when I set twig timezone

Thank you, I guess I managed to make it work but I'm not sure if this is good and will not have problems with multi-users (I do not know how symfony works with multi-thread or multi-request from different users) at the same time as I do:

$this->twig->getExtension('core')->setTimeZone($user->getTimezone()->getZone());

I tried with two browsers fetching the different pages and setting a new timezone for each different user logged in. It works and does not override the other user's timezone. I thought it would because it changes the default timezone for twig core but I removed the line I modify the timezone, after the user logged in and has set already the value, I reloaded the page and it was set back to UTC.

Does it mean that those global variables are only for one request ?

I am not used to symfony2 for handling requests and how it works for variables and cache.

I looked for many solutions: example example2 example3

My code:

class TwigDateRequestListener
{
    protected $twig;
    private $context;

    function __construct(\Twig_Environment $twig, SecurityContext $context)
    {
        $this->twig = $twig;
        $this->context = $context;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        $user = $this->context->getToken()->getUser();
        if ($user != 'anon.') {
            $user = SaasUserQuery::create()->findPk($user->getId());
            $this->twig->getExtension('core')->setTimeZone($user->getTimezone()->getZone());
        } else {
            $this->twig->getExtension('core')->setTimeZone('Europe/Paris');
        }
    }
}

Then in the view I only need to write 'date('H:i:s')', and it is the user's timezone and if not logged in on Paris timezone.

Is it good? I am not sure about multi-request from different users at the same time. For example:

Important: One user make a request he is in the controller action method (the timezone has been set), a second user make a request he has a different timezone than the first user. Now both controller make the call to render and the view is rendered and returned to users.

Precisely here, what happens ? Both get good dates in their respective timezone or the first user get dates in the second user timezone ?

Community
  • 1
  • 1
Yoann CAPLAIN
  • 121
  • 3
  • 11

1 Answers1

4

I would go with a third method with which you can reduce a lot of code. You can set the default timezone for the date filter in twig

$twig = new Twig_Environment($loader);
$twig->getExtension('core')->setTimezone('Europe/Paris');
DarkBee
  • 16,592
  • 6
  • 46
  • 58
  • 1
    Thank you for that but if I do that I still have to specify in twig's view the timezone otherwise the default is used and it will be Paris timezone. I can set the user's timezone in twig core but I do not want what happens on multi-request from different users with different timezones. I edited my post to explain the problem. – Yoann CAPLAIN Sep 23 '16 at 04:50
  • 1
    The timezone is set for each seperate request. That's how PHP works. [example](http://www.darkbee.be/stack/date/ajax.php) – DarkBee Sep 23 '16 at 06:09