2012-05-22 53 views
6

我的當前項目的一個要求是允許用戶爲他們的帳戶選擇一個時區,然後在整個時區使用該時區的所有日期/時間相關功能整個網站。Symfony2:在哪裏設置用戶定義的時區

我看到它的方式,我有兩個選擇:

  • 傳遞一個DateTimeZone對象爲DateTime的構造函數中使用PHP的date_default_timezone_set()

每一個新的DateTime

  • 設置默認時區似乎使用date_default_timezone_set是要走的路,但我不確定我應該在哪裏設置它。由於每個用戶的時區都不相同,並且在整個站點中都使用了DateTime,所以我需要將它設置爲會影響所有頁面的某個位置。

    也許我可以寫一個事件監聽器,它設置它成功登錄後?如果我採用這種方法,它會保持在所有頁面上設置,還是隻在每個頁面上設置?

    我很想聽聽別人會怎麼做。

  • 回答

    14

    是的,你可以使用一個事件監聽器,掛在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()}'"); 
        } 
    } 
    
    +3

    @elnur,假設我的服務器設置爲「UTC」和用戶「美洲/加拉加斯」。使用您的解決方案,當用戶在某個實體字段中提交日期時間時會發生什麼?將日期時間與用戶時區(與用戶輸入的值相比沒有變化)或服務器時區(值更改爲與UTC時間相匹配)一起存儲? –

    +0

    @David你應該只在你的數據庫中存儲基於UTC的時間/日期。這樣,您可以始終正確地爲用戶設置格式。 – Luke