Symfony2:在哪里设置用户定义的时区


Symfony2: Where to set a user defined time zone

我对当前项目的要求之一是允许用户为其帐户选择一个时区,然后将此时区用于整个站点中与日期/时间相关的所有功能。

在我看来,我有两个选择:

  • 将 DateTimeZone 对象传递给每个新 DateTime 的 DateTime 构造函数
  • 使用 PHP 的date_default_timezone_set()设置默认时区

似乎使用 date_default_timezone_set 是要走的路,但我不确定我应该在哪里设置它。 由于时区因用户而异,并且整个站点都使用日期时间,因此我需要将其设置在会影响所有页面的位置。

也许我可以编写一个事件侦听器,在成功登录后设置它? 如果我采用这种方法,它是在所有页面上保持设置还是仅按页面设置?

我很想听听其他人会如何处理这个问题。

是的,您可以使用事件侦听器,挂接kernel.request事件。

这是我的一个项目的听众:

<?php
namespace Vendor'Bundle'AppBundle'Listener;
use Symfony'Component'Security'Core'SecurityContextInterface;
use Doctrine'DBAL'Connection;
use JMS'DiExtraBundle'Annotation'Service;
use JMS'DiExtraBundle'Annotation'Observe;
use JMS'DiExtraBundle'Annotation'InjectParams;
use JMS'DiExtraBundle'Annotation'Inject;
/**
 * @Service
 */
class TimezoneListener
{
    /**
     * @var 'Symfony'Component'Security'Core'SecurityContextInterface
     */
    private $securityContext;
    /**
     * @var 'Doctrine'DBAL'Connection
     */
    private $connection;
    /**
     * @InjectParams({
     *     "securityContext" = @Inject("security.context"),
     *     "connection"      = @Inject("database_connection")
     * })
     *
     * @param 'Symfony'Component'Security'Core'SecurityContextInterface $securityContext
     * @param 'Doctrine'DBAL'Connection $connection
     */
    public function __construct(SecurityContextInterface $securityContext, Connection $connection)
    {
        $this->securityContext = $securityContext;
        $this->connection      = $connection;
    }
    /**
     * @Observe("kernel.request")
     */
    public function onKernelRequest()
    {
        if (!$this->securityContext->isGranted('ROLE_USER')) {
            return;
        }
        $user = $this->securityContext->getToken()->getUser();
        if (!$user->getTimezone()) {
            return;
        }
        date_default_timezone_set($user->getTimezone());
        $this->connection->query("SET timezone TO '{$user->getTimezone()}'");
    }
}