php – Symfony2: How can I set twig |date("d F, Y") filter to output months in Swedish?-ThrowExceptions

Exception or error:

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?

How to solve:

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 }

Answer:

|date filter use DateTime::format function which doesnt support locales. See this question and write your own twig extension.

Answer:

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

Answer:

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 

Leave a Reply

Your email address will not be published. Required fields are marked *