2012-02-28 18 views
15

Para dar formato a una fecha en la ramita que suelen utilizar algo como:Localizar en ramitas usando Symfony 2

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

Ahora, tengo que localizar esta fecha (US m/d/a, NL d/m/y) ¿Cuál sería la mejor práctica para hacer esto en la ramita? Utilizo Symfony 2, una solución sería hacer la traducción en el controlador, pero me gustaría hacer esto en la rama.

+0

posible duplicado de [Cómo hacer que un objeto DateTime en una plantilla Twig] (http://stackoverflow.com/questions/8318914/how-to-render- a-datetime-object-in-a-twig-template) –

+0

Para hacer esto con sf2, hay un paquete: https://github.com/sonata-project/SonataIntlBundle –

+0

@YohanG., El paquete proporcionado no cambia el comportamiento del filtro '| date'. Define nuevos filtros que no es el comportamiento deseado con respecto a la pregunta OP – Trix

Respuesta

39

¿Qué hay de the Intl Twig extension?

Uso de una plantilla ramita:

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

Gran sugerencia. Simplemente no olvide registrar la extensión Intl, como se explica aquí: http://nerdpress.org/2011/10/19/symfony-2-twig-enabling-native-twig-extensions/ (esa página explica cómo instalar Debug extensión, pero la instalación de la Intl sucede de manera análoga) – Martijn

+2

Esta debería ser la respuesta aceptada. Consulte [mi respuesta a otra pregunta] (http://stackoverflow.com/a/23424315/1001110) para obtener más información sobre cómo usar la extensión Intl. –

+1

¡Hay un gran problema, en la documentación de twig sobre este filtro, no hay ninguna mención sobre cómo instalarlo! – SaidbakR

4

no quería instalar todo un extensiones sólo para estas cosas y la necesidad de hacer algunas cosas de forma automática: También es posible escribir un helperclass (o ampliar un ayudante existente) en el paquete/ramita/Extensiones por ejemplo, así:

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

ramita-Plantilla:

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

El resultado es "12. De febrero de 2014" (o '12. Februar 2014' en es_ES etc.)

+0

Estaba realmente buscando algo en toda la aplicación no solo Twig y esto ayudó, ¡gracias! –

+0

¡De nada! Gracias por sus comentarios positivos :) – Franziska

0

En realidad sólo quería los nombres días & mes para ser traducidos según la localización y escribí esta extensión ramita. Acepta los parámetros normales y DateTime->format() convierte día & nombres de meses usando strftime() si es necesario.

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