我存储在我的数据库日期大多数时间与DateTime在MySQL上的UTC时间。我使用Symfony 2.4.5(是的,它是旧的)。
我使用来自Propel的普通sql查询从控制器检索日期。因为我不想一直从数据库中查询用户的时区,所以我将在会话中保存用户的时区'{'timezone'=> 'Europe/Paris'}。
我应该在控制器中转换从DB检索到的日期还是在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的回答:
首先我尝试在树枝视图:
- 日期(H:我:年代",user_timezone.zone)
- 日期(H:我:年代",app.session.get("时区"))
- 日期(H:我:年代")
- 日期(H:我:年代","欧洲/巴黎")
- 日期(H:我:年代","亚洲/上海")
日期(H:我:年代",假)
用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
In控制器:
$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 core的默认时区,但我删除了我修改时区的行,在用户登录并设置了已经设置的值之后,我重新加载了页面,它被设置回UTC。
是否意味着这些全局变量只适用于一个请求?
我不习惯symfony2处理请求,也不习惯它是如何处理变量和缓存的。
我寻找了许多解决方案:例子example2青年们
我代码: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')',这是用户的时区,如果没有登录在巴黎时区。
好吗?我不确定在同一时间来自不同用户的多个请求。例如:
重要:一个用户发出请求时,他在控制器动作方法中(时区已设置),第二个用户发出请求时,他的时区与第一个用户不同。现在两个控制器都调用渲染,视图被渲染并返回给用户。
就在这里,发生了什么?
我会选择第三种方法,使用这种方法可以减少大量代码。您可以在twig
中设置日期过滤器的默认时区。$twig = new Twig_Environment($loader);
$twig->getExtension('core')->setTimezone('Europe/Paris');