Php 如何在symfony3中使用时区
我正在UTC时区中存储所有时间/日期时间。我想让用户指定他想在哪个时区查看小时/日期-就像在任何其他论坛(phpbb、ipb等…) 到目前为止我所做的: 在Php 如何在symfony3中使用时区,php,symfony,Php,Symfony,我正在UTC时区中存储所有时间/日期时间。我想让用户指定他想在哪个时区查看小时/日期-就像在任何其他论坛(phpbb、ipb等…) 到目前为止我所做的: 在config.yml中,我设置了新的条令类型: types: datetime: AppBundle\DoctrineExtensions\DBAL\Types\UTCDateTimeType datetimetz: AppBundle\DoctrineExtensions\DBAL\Types\UTCDateTimeType
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());
}
}
doctrine:
dbal:
types:
utcdatetime:
name: datetime
class: AppBundle\Doctrine\DBAL\Types\UTCDateTimeType
并将我的php.ini
配置为UTC
。现在麻烦来了:
操作
date\u default\u timezone\u get()。有什么办法让它工作吗?你很接近了。实际上,您可以简化一点:
在config.yml
中,您只需覆盖datetime
:
<?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());
}
}
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
侦听器不需要设置服务器时区,只需要设置细枝时区:
你很接近。实际上,您可以简化一点:
在config.yml
中,您只需覆盖datetime
:
<?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());
}
}
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
侦听器不需要设置服务器时区,只需要设置细枝时区: