I'm having problems with the |date("d F, Y") filter in my twig templates.
I want the months to be outputted in Swedish. I have tried setting "locale: sv" in my parameters.yml files but I get no effect.
It was working before I upgraded to from Symfony 2.1 to 2.3 so I think that might have something to do with it.
Any thoughts on how to fix this?
The Twig Intl Extension
You can use the Twig Intl Extension found in fabpot's official Twig extension repository.
It provides a localized date filter which can be used like this:
{{ date | localizeddate('full', 'none', app.request.locale ) }}
use app.request.locale
as third parameter for current locale or just 'sv'
.
Integration into your project
add the official extensions to your composer.json
using:
composer require twig/extensions:1.0.*@dev
composer update twig/extensions
config.yml
#enable intl extensions
services:
twig.extension.intl:
class: Twig_Extensions_Extension_Intl
tags:
- { name: twig.extension }
quick tip:
another handy extension is the Text extension providing truncate,...etc filters
services:
twig.extension.text:
class: Twig_Extensions_Extension_Text
tags:
- { name: twig.extension }
|date
filter use DateTime::format
function which doesnt support locales. See this question and write your own twig extension.
I didn't really like the Twig Intl extension, it felt a bit bloated for my use case thus I went with a different approach. In our application we extended the DateTime object and overloaded the format
function to translate the date using PHP's strftime
function.
A few things should be considered here before using this approach:
- Our application uses a single language (Dutch in our case)
- We use our extended DateTime object everywhere in the application
- Extending the DateTime class will cause other issues, for example in Doctrine you will have to implement a custom Type to handle your extended DateTime and not all libraries use the
DateTimeInterface
correctly but expect \DateTime
objects
Here's the DateTime class:
YourNameSpace;
class DateTime extends \DateTime {
public static function createFromFormat($format, $time, $timezone = null) {
$dateTime = parent::createFromFormat($format, $time, $timezone);
// we want to return a <YourNameSpace>\DateTime instead of a 'normal' DateTime, thus we have to instantiate one
// note that this returns `null` instead of `false` so you can use nullable return types `?DateTime` and the `??` operator
return $dateTime && $dateTime->format($format) == $time ? (new DateTime())->setTimestamp($dateTime->getTimestamp()) : null;
}
const FORMAT_LOCALE_MAP = [
'F' => '%B', // full textual representation of a month, such as January or March
'M' => '%b', // short textual representation of a month, three letters
'l' => '%A', // full textual representation of the day of the week
'D' => '%a' // short textual representation of a day, three letters
// add any other if your application needs it
];
public function format($format): string {
$formattedDate = parent::format($format);
// localize string
foreach(self::FORMAT_LOCALE_MAP as $dateFormat => $strftimeFormat) {
if(strpos($format, $dateFormat) !== false) {
$formattedDate = str_replace(parent::format($dateFormat), strftime($strftimeFormat, $this->getTimestamp()), $formattedDate);
}
}
return $formattedDate;
}
}
Then in your front controller (i.e. public/index.php
) set your locale:
setlocale(LC_ALL, 'nl_NL');
Now in your Twig template, anywhere a DateTime is formatted:
// start is an instance of your extended DateTime object
{{ start.format('D d M')|capitalize }}
// Do 06 dec
I will make an addition to solution posted by @nifr.
In order to use your date format install the Twig Intl Extension and than you can use:
{{ date|localizeddate('none', 'none', app.request.locale, null, 'dd MMMM, yyyy') }}
The last argument in my example is a date format - here is a documentation: http://userguide.icu-project.org/formatparse/datetime
Here is the Twig Intl Extension documentation: https://twig-extensions.readthedocs.io/en/latest/intl.html