【问题标题】:Symfony convert to user's timezone in controller or twigSymfony 在控制器或树枝中转换为用户的时区
【发布时间】:2016-09-22 14:26:44
【问题描述】:

我大部分时间都在我的数据库中使用 UTC 时间在 MySQL 上的 DateTime 存储日期。我正在使用 Symfony 2.4.5(是的,它很旧)。

我使用 Propel 的普通 sql 查询从控制器中检索日期。 由于我不想一直从数据库中查询用户时区,我将在会话中保存用户的时区 '{'timezone'=> 'Europe/Paris'}。

我应该在控制器中转换从数据库检索到的日期还是在 Twig 中转换?

// In controller
$dictionaryThatHaveOtherData = ...
$dateFromDbInUTC = UserQuery::Create()->...
$dateFromDbInUTC->setTimeZone(new DateTimeZone($this->get('session')->get('timezone')));
$dictionaryThatHaveOtherData['dateForSomething'] = $dateFromDbInUTC;
// In Twig
{{ dateForSomething | date('theFormatIWant') }}

或者改为在 Twig 中进行转换:

// In controller
$dictionaryThatHaveOtherData = ...
$dateFromDbInUTC = UserQuery::Create()->...    
$dictionaryThatHaveOtherData['dateForSomething'] = $dateFromDbInUTC;
// In Twig
{{ dateForSomething | date('theFormatIWant', app.session.timezone) }}

我想最好在控制器中做,因为视图只关心以所需格式显示数据,而不涉及很多事情,比如考虑日期是否已经在正确的时区。

如果视图需要在日期之间进行比较,在 UTC 或用户时区会更好吗?有区别吗?


自 DarkBee 回答后编辑:

首先我在树枝视图中尝试:

  • date('H:i:s', user_timezone.zone)
  • date('H:i:s', app.session.get('timezone'))
  • 日期('H:i:s')
  • date('H:i:s', 'Europe/Paris')
  • date('H:i:s', '亚洲/上海')
  • 日期('H:i:s', false)

    使用 UTC 时区发送以查看

  • 19:00:00

  • 19:00:00
  • 11:00:00
  • 13:00:00
  • 19:00:00
  • 11:00:00

    发送到上海时区查看

  • 19:00:00

  • 19:00:00
  • 11:00:00
  • 13:00:00
  • 19:00:00
  • 19:00:00

    在控制器中:$this->get('Twig')->getExtension('core')->setTimezone('Europe/Paris');

  • 19:00:00

  • 19:00:00
  • 13:00:00
  • 13:00:00
  • 19:00:00
  • 11:00:00

    在控制器中:$this->get('Twig')->getExtension('core')->setTimezone($this->get('session')->get('timezone'));

  • 19:00:00

  • 19:00:00
  • 19:00:00
  • 13:00:00
  • 19:00:00
  • 11:00:00

    在控制器和日期与上海时区:$this->get('Twig')->getExtension('core')->setTimezone('Europe/Paris');

  • 19:00:00

  • 19:00:00
  • 13:00:00
  • 13:00:00
  • 19:00:00
  • 19:00:00

所以是的,我们看到 'date('H:i:s')' 是我设置 twig 时区的好时机

谢谢,我想我设法让它工作了,但我不确定这是否很好,并且不会有多用户问题(我不知道 symfony 如何处理来自的多线程或多请求不同的用户)和我同时做:

$this->twig->getExtension('core')->setTimeZone($user->getTimezone()->getZone());

我尝试使用两个浏览器来获取不同的页面并为每个不同的登录用户设置一个新的时区。它可以工作并且不会覆盖其他用户的时区。我认为会是因为它更改了 twig 核心的默认时区,但我删除了修改时区的行,在用户登录并设置了值后,我重新加载了页面并将其设置回 UTC。

是不是说那些全局变量只针对一个请求?

我不习惯 symfony2 处理请求以及它如何处理变量和缓存。

我寻找了许多解决方案: example example2 example3

我的代码:

class TwigDateRequestListener
{
    protected $twig;
    private $context;

    function __construct(\Twig_Environment $twig, SecurityContext $context)
    {
        $this->twig = $twig;
        $this->context = $context;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        $user = $this->context->getToken()->getUser();
        if ($user != 'anon.') {
            $user = SaasUserQuery::create()->findPk($user->getId());
            $this->twig->getExtension('core')->setTimeZone($user->getTimezone()->getZone());
        } else {
            $this->twig->getExtension('core')->setTimeZone('Europe/Paris');
        }
    }
}

然后在视图中我只需要写'date('H:i:s')',它是用户的时区,如果没有登录巴黎时区。

好吃吗?我不确定同时来自不同用户的多个请求。 例如:

重要: 一个用户发出请求,他在控制器操作方法中(时区已设置),第二个用户发出请求,他的时区与第一个用户不同。现在两个控制器都调用了 render 并且视图被渲染并返回给用户。

正是在这里,会发生什么?两者都在各自的时区获得好日期,还是第一个用户在第二个用户时区获得日期?

【问题讨论】:

    标签: symfony date datetime timezone twig


    【解决方案1】:

    我会采用第三种方法,通过它可以减少大量代码。 您可以在 twig 中为日期过滤器设置默认时区

    $twig = new Twig_Environment($loader);
    $twig->getExtension('core')->setTimezone('Europe/Paris');
    

    【讨论】:

    • 谢谢你,但如果我这样做了,我仍然必须在 twig 的视图中指定时区,否则使用默认值,它将是巴黎时区。我可以在 twig 核心中设置用户的时区,但我不希望来自不同时区的不同用户的多请求会发生什么。我编辑了我的帖子来解释这个问题。
    • 为每个单独的请求设置时区。这就是 PHP 的工作原理。 example
    猜你喜欢
    • 2021-08-10
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    相关资源
    最近更新 更多