【问题标题】:Symfony2: Where to set a user defined time zoneSymfony2:在哪里设置用户定义的时区
【发布时间】:2012-05-28 11:43:34
【问题描述】:

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

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

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

似乎使用 date_default_timezone_set 是可行的方法,但我不确定我应该在哪里设置它。因为时区会因用户而异,并且整个网站都使用 DateTime,所以我需要将其设置在会影响所有页面的位置。

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

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

【问题讨论】:

    标签: php symfony timezone


    【解决方案1】:

    是的,您可以使用事件侦听器,挂钩 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()}'");
        }
    }
    

    【讨论】:

    • @elnur,假设我的服务器设置为“UTC”,用户设置为“America/Caracas”。使用您的解决方案,当用户在某个实体字段中提交日期时间时会发生什么?日期时间将与用户时区(与用户输入的值相比没有变化)或服务器时区(值已更改以匹配 UTC 时间)一起存储?
    • @David 您应该只在数据库中存储基于 UTC 的时间/日期。这样您就可以始终为用户正确格式化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 2011-05-01
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多