[英]How to use timezone with symfony3
我將所有時間/日期時間存儲在UTC時區中。 我想允許用戶指定他想在哪個時區查看小時/日期 - 比如在任何其他論壇(phpbb,ipb等等......)
到目前為止我做了什么:
在config.yml
我設置了新的學說類型:
types:
datetime: AppBundle\DoctrineExtensions\DBAL\Types\UTCDateTimeType
datetimetz: AppBundle\DoctrineExtensions\DBAL\Types\UTCDateTimeType
time: AppBundle\DoctrineExtensions\DBAL\Types\UTCTimeType
恩。 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.ini
配置為UTC
。 現在出現了麻煩:
來自UTCDateTimeType::getDefaultTimeZone()
action date_default_timezone_get()
在UTCDateTimeType::getDefaultTimeZone()
之前運行, onKernelRequest
設置為用戶的時區,因此所有日期都在服務器的UTC
時區中。 任何想法如何使其工作?
你很近。 你實際上可以簡化一下:
在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
監聽器不需要設置服務器時區,只需要設置Twig時區:
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());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.