2012-02-28 27 views
15

Để định dạng một ngày trong cành lá bạn thường sử dụng một cái gì đó như:Localize ngày cành sử dụng Symfony 2

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

Bây giờ, tôi có để bản địa hoá ngày này (US m/d/y, NL d/m/y). Điều gì sẽ là thực hành tốt nhất để làm điều này trong cành cây? Tôi sử dụng Symfony 2, một workaround sẽ được làm bản dịch trong bộ điều khiển nhưng tôi muốn làm điều này trong cành cây.

+0

thể trùng lặp của [Làm thế nào để làm cho một đối tượng DateTime trong một mẫu Twig] (http://stackoverflow.com/questions/8318914/how-to-render- a-datetime-object-in-a-twig-template) –

+0

Để thực hiện việc này với sf2, có một gói: https://github.com/sonata-project/SonataIntlBundle –

+0

@YohanG., Gói được cung cấp không thay đổi hành vi của bộ lọc '| date'. Nó định nghĩa các bộ lọc mới mà không phải là hành vi mong muốn liên quan đến câu hỏi OP – Trix

Trả lời

39

Còn khoảng the Intl Twig extension thì sao?

Cách sử dụng trong một mẫu cành lá:

{{ my_date | localizeddate('full', 'none', locale) }} 
+0

Đề xuất tuyệt vời. Chỉ cần đừng quên đăng ký mở rộng Intl, như được giải thích tại đây: http://nerdpress.org/2011/10/19/symfony-2-twig-enabling-native-twig-extensions/ (trang đó giải thích việc cài đặt Debug mở rộng, nhưng cài đặt Intl xảy ra tương tự) – Martijn

+2

Đây phải là câu trả lời được chấp nhận. Xem [câu trả lời của tôi về một câu hỏi khác] (http://stackoverflow.com/a/23424315/1001110) để biết thêm thông tin về cách sử dụng tiện ích mở rộng Intl. –

+1

Có một vấn đề lớn, trong tài liệu hướng dẫn về bộ lọc này, không có bất kỳ đề cập nào về cách cài đặt nó! – SaidbakR

4

Tôi không muốn cài đặt toàn bộ một phần mở rộng chỉ dành riêng cho công cụ này và cần phải làm một vài điều tự động: Cũng có thể viết một helperclass (hoặc mở rộng một helper hiện hành) tại Bundle/cành/Extensions ví dụ như thế này:

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); 
} 

cành lá-Template:

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

Kết quả là "12. Tháng 2 năm 2014 "(hoặc" 12. Februar 2014 "trong de_DE, v.v.)

+0

Tôi đã thực sự tìm kiếm một cái gì đó ứng dụng rộng không chỉ Twig và điều này đã giúp, cảm ơn! –

+0

Bạn được chào đón! Cảm ơn bạn đã phản hồi tích cực của bạn :) – Franziska

0

Tôi thực sự chỉ muốn ngày tháng & tên tháng được dịch theo ngôn ngữ và đã viết phần mở rộng cành này. Nó chấp nhận thông số DateTime->format() thông thường và chuyển đổi ngày tháng & tên sử dụng strftime() nếu cần thiết.

<?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; 
    } 
}