簡體   English   中英

如何使用symfony3時區

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM