使用 Symfony 2 本地化树枝中的日期

Posted

技术标签:

【中文标题】使用 Symfony 2 本地化树枝中的日期【英文标题】:Localize dates in twigs using Symfony 2 【发布时间】:2012-03-17 19:54:25 【问题描述】:

要在 twig 中格式化日期,您通常使用以下内容:

 meeting.date|date("m/d/Y") 

现在,我必须本地化这个日期(美国 m/d/y,NL d/m/y)。在树枝中执行此操作的最佳做​​法是什么?我确实使用 Symfony 2,一种解决方法是在控制器中进行翻译,但我想在树枝中这样做。

【问题讨论】:

要使用 sf2 执行此操作,有一个捆绑包:github.com/sonata-project/SonataIntlBundle How to render a DateTime object in a Twig template的可能重复 @YohanG.,提供的包不会改变 |date 过滤器的行为。它定义了新的过滤器,这不是关于 OP 问题的理想行为 【参考方案1】:

the Intl Twig extension 呢?

在树枝模板中的使用:

 my_date | localizeddate('full', 'none', locale) 

【讨论】:

很好的建议。只是不要忘记注册 Intl 扩展,如下所述:nerdpress.org/2011/10/19/…(该页面解释了安装 Debug 扩展,但安装 Intl 的过程类似) 这应该是公认的答案。有关如何使用 Intl 扩展的更多信息,请参阅my answer on another question。 有个大问题,在twig文档中关于这个过滤器,没有提到如何安装! This answer 告诉如何用composer安装它 有用,但似乎不是一个可靠的解决方案,因为应该更改 twig 文件中的所有 |date 过滤器【参考方案2】:

我不想仅仅为这些东西安装一个完整的扩展,需要自动做一些事情:也可以在 Bundle/Twig/Extensions 中编写一个帮助类(或扩展现有的帮助),例如像这样:

public function foo(\Datetime $datetime, $lang = 'de_DE', $pattern = 'd. MMMM Y')

    $formatter = new \IntlDateFormatter($lang, \IntlDateFormatter::LONG, \IntlDateFormatter::LONG);
    $formatter->setPattern($pattern);
    return $formatter->format($datetime);

树枝模板:

 yourDateTimeObject|foo('en_US', 'd. MMMM Y') 

结果是“2014 年 2 月 12 日”(或 de_DE 中的“2014 年 2 月 12 日”等)

【讨论】:

我真的在寻找应用范围内的东西,而不仅仅是 Twig,这对我有帮助,谢谢! 不客气!感谢您的积极反馈:)【参考方案3】:

我真的只想根据语言环境翻译日期和月份名称,并编写了这个树枝扩展。它接受普通的DateTime->format() 参数,并在需要时使用strftime() 转换日期和月份名称。

<?php

namespace AppBundle\Twig\Extension;

use Twig_Extension;
use Twig_SimpleFilter;
use DateTimeZone;
use DateTime;

class LocalizedDateExtension extends Twig_Extension

    protected static $conversionMap = [
        'D' => 'a',
        'l' => 'A',
        'M' => 'b',
        'F' => 'B',
    ];

    public function getFilters()
    
        return [
            new Twig_SimpleFilter('localizeddate', [$this, 'localizeDate']),
        ];
    

    protected static function createLocalizableTodo(&$formatString)
    
        $newFormatString = '';
        $todo = [];

        $formatLength = mb_strlen($formatString);
        for ($i = 0; $i < $formatLength; $i++) 
            $char = $formatString[$i];
            if ('\'' === $char) 
                $newFormatString = $formatString[++$i]; //advance and add new character
            
            if (array_key_exists($char, static::$conversionMap)) 
                $newFormatString.= '\!\L\O\C\A\L\I\Z\E\D\\'; //prefix char
                $todo[$char] = static::$conversionMap[$char];
            
            $newFormatString.= $char;
        
        $formatString = $newFormatString;
        return $todo;
    

    public function localizeDate(DateTime $dateTime, $format, $timezone = null, $locale = null)
    
        if (null !== $timezone && $dateTime->getTimezone()->getName() !== $timezone) 
            $dateTime = clone $dateTime;
            $dateTime->setTimezone(new DateTimeZone($timezone));
        

        $todo = static::createLocalizableTodo($format);
        $output = $dateTime->format($format);

        //no localizeable parameters?
        if (0 === count($todo)) 
            return $output;
        

        if ($locale !== null) 
            $currentLocale = setlocale(LC_TIME, '0');
            setlocale(LC_TIME, $locale);
        
        if ($timezone !== null) 
            $currentTimezone = date_default_timezone_get();
            date_default_timezone_set($timezone);
        

        //replace special parameters
        foreach ($todo as $placeholder => $parameter) 
            $output = str_replace('!LOCALIZED'.$placeholder, strftime('%'.$parameter, $dateTime->getTimestamp()), $output);
        
        unset($parameter);

        if (isset($currentLocale)) 
            setlocale(LC_TIME, $currentLocale);
        
        if (isset($currentTimezone)) 
            date_default_timezone_set($currentTimezone);
        

        return $output;
    

【讨论】:

以上是关于使用 Symfony 2 本地化树枝中的日期的主要内容,如果未能解决你的问题,请参考以下文章

树枝扩展中的 Symfony 依赖注入

Symfony 2 树枝拆分功能未按预期工作

从日期到字符串的树枝过滤器

Symfony 异常,使用控制器和树枝模板的数据库查询

Symfony 树枝控制器路由

在Twig模板中使用4位数年份的本地化日期