2017-03-22 36 views
1

我使用UTC時區存儲所有時間/日期時間。我想允許用戶指定在哪個時區,他想要觀看時間/日期 - 任何其他的論壇也像(PHPBB,平局等...)如何使用symfony3的時區

我做了什麼至今:

config.yml我已經設定了新的教義類型:

types: 
    datetime: AppBundle\DoctrineExtensions\DBAL\Types\UTCDateTimeType 
    datetimetz: AppBundle\DoctrineExtensions\DBAL\Types\UTCDateTimeType 
    time: AppBundle\DoctrineExtensions\DBAL\Types\UTCTimeType 

ex。 UTDDateTime

<?php 

namespace AppBundle\DoctrineExtensions\DBAL\Types; 

use DateTime; 
use DateTimeZone; 
use Doctrine\DBAL\Platforms\AbstractPlatform; 
use Doctrine\DBAL\Types\ConversionException; 
use Doctrine\DBAL\Types\DateTimeType; 

class UTCDateTimeType extends DateTimeType 
{ 
    /** @var DateTimeZone */ 
    private static $utc; 
    /** @var DateTimeZone */ 
    private static $defaultTimeZone; 

    /** 
    * @param DateTime $dateTime 
    * @param AbstractPlatform $platform 
    * 
    * @return string|null 
    */ 
    public function convertToDatabaseValue($dateTime, AbstractPlatform $platform) 
    { 
     if ($dateTime instanceof DateTime) { 
      $dateTime->setTimezone(self::getUtc()); 
     } 
     return parent::convertToDatabaseValue($dateTime, $platform); 
    } 

    /** 
    * @param string $dateTimeString 
    * @param AbstractPlatform $platform 
    * 
    * @throws ConversionException 
    * 
    * @return DateTime|null 
    */ 
    public function convertToPHPValue($dateTimeString, AbstractPlatform $platform) 
    { 
     if (null === $dateTimeString || $dateTimeString instanceof DateTime) { 
      return $dateTimeString; 
     } 
     $dateTime = DateTime::createFromFormat($platform->getDateTimeFormatString(), $dateTimeString, self::getUtc()); 
     if (!$dateTime) { 
      throw ConversionException::conversionFailedFormat(
       $dateTimeString, 
       $this->getName(), 
       $platform->getDateTimeFormatString() 
      ); 
     } 
     // set time zone 
     $dateTime->setTimezone(self::getDefaultTimeZone()); 
     return $dateTime; 
    } 

    /** 
    * @return DateTimeZone 
    */ 
    private static function getUtc() 
    { 
     return self::$utc ? self::$utc : self::$utc = new DateTimeZone('UTC'); 
    } 

    /** 
    * @return DateTimeZone 
    */ 
    private static function getDefaultTimeZone() 
    { 
     return self::$defaultTimeZone 
      ? self::$defaultTimeZone : self::$defaultTimeZone = new DateTimeZone(date_default_timezone_get()); 
    } 
} 

我已經做了一個onKernelRequest聽衆:

class TimezoneListener 
{ 
    /** 
    * @var AppSettingsService 
    */ 
    private $settings; 

    /** 
    * @var \Twig_Environment 
    */ 
    protected $twig; 

    public function __construct(AppSettingsService $settings, \Twig_Environment $twig) 
    { 
     $this->twig = $twig; 
     $this->settings = $settings->getAppSettings(); 
    } 

    public function onKernelRequest(GetResponseEvent $event) 
    { 
     date_default_timezone_set($this->settings->getDefaultTimeZone()); 
     $this->twig->getExtension('Twig_Extension_Core')->setTimezone($this->settings->getDefaultTimeZone()); 
    } 
} 

和配置我php.iniUTC。現在來的煩惱:

行動onKernelRequest將其設置爲用戶的時區從date_default_timezone_get()運行UTCDateTimeType::getDefaultTimeZone()以前那麼所有的日期是在服務器的UTC時區。任何想法如何使它工作?

回答

0

你非常接近。實際上,你可以簡化一下:

config.yml你只需要重寫datetime

doctrine: 
    dbal: 
     types: 
      utcdatetime: 
       name: datetime 
       class: AppBundle\Doctrine\DBAL\Types\UTCDateTimeType 


UTCDateTimeType你只需要確保UTC日期時間存儲在數據庫:

namespace AppBundle\Doctrine\DBAL\Types; 


use Doctrine\DBAL\Platforms\AbstractPlatform; 
use Doctrine\DBAL\Types\ConversionException; 
use Doctrine\DBAL\Types\DateTimeType; 

/** 
* Class UTCDateTimeType 
* 
* @package AppBundle\Doctrine\DBAL\Types 
*/ 
class UTCDateTimeType extends DateTimeType 
{ 
    /** 
    * @var \DateTimeZone 
    */ 
    private static $utc = null; 

    /** 
    * @param mixed   $value 
    * @param AbstractPlatform $platform 
    * 
    * @return mixed 
    */ 
    public function convertToDatabaseValue($value, AbstractPlatform $platform) 
    { 
     if ($value instanceof \DateTime) { 
      $value->setTimezone(self::getUtc()); 
     } 

     return parent::convertToDatabaseValue($value, $platform); 
    } 

    /** 
    * @param mixed   $value 
    * @param AbstractPlatform $platform 
    * 
    * @return $this|mixed 
    * @throws ConversionException 
    */ 
    public function convertToPHPValue($value, AbstractPlatform $platform) 
    { 
     if (null === $value || $value instanceof \DateTime) { 
      return $value; 
     } 

     $converted = \DateTime::createFromFormat(
      $platform->getDateTimeFormatString(), 
      $value, 
      self::$utc ? self::$utc : self::$utc = new \DateTimeZone('UTC') 
     ); 

     if (!$converted) { 
      throw ConversionException::conversionFailedFormat(
       $value, 
       $this->getName(), 
       $platform->getDateTimeFormatString() 
      ); 
     } 

     return $converted; 
    } 

    /** @return \DateTimeZone */ 
    private static function getUtc() 
    { 
     if (self::$utc === null) { 
      self::$utc = new \DateTimeZone('UTC'); 
     } 

     return self::$utc; 
    } 
} 


最後,您的onKernelRequest聽衆不需要設置服務器時區,只是細枝時區:

class TimezoneListener 
{ 
    /** 
    * @var AppSettingsService 
    */ 
    private $settings; 

    /** 
    * @var \Twig_Environment 
    */ 
    protected $twig; 

    public function __construct(AppSettingsService $settings, \Twig_Environment $twig) 
    { 
     $this->twig = $twig; 
     $this->settings = $settings->getAppSettings(); 
    } 

    public function onKernelRequest(GetResponseEvent $event) 
    { 
     $this->twig->getExtension('Twig_Extension_Core')->setTimezone($this->settings->getDefaultTimeZone()); 
    } 
}