How to use Twig date to show week day in Chinese t

2019-07-19 17:26发布

问题:

I want to show the date format like: 10月09日, 周三 (which means 10/9, Wed.)
and my data is UNIX time like [message.time]: 1380813820000

so this is what I do in twig:
{{ (message.time/1000)|date("m月d日, 周w") }}
But it show me: 10月09日,周3, Because date "w" are numbers, not Chinese text.

so can I do anything by Twig to converse the text format?

thanks

回答1:

The underlying problem is, that Twig uses the DateTime::format method, which does not support locales or (as far as I know) any other type of functionality to translate the names of the weekdays.

There are three solutions:

  • Use strftime, which supports locales (and thus localized weekday-names).
  • If you can use the intl extension of PHP, then you can use the Twig-extensions which comes with a intl extension for Twig.
  • You translate the weekdays by yourself.

Plus to use your preferred solution in a Twig-template, you have to extend the functionality of Twig.

Using strftime and setlocale

The following (rather large) code implements the strftime solution:

<?php

// inspired by phpdude:
// https://github.com/fabpot/twig/issues/378#issuecomment-4698225
class DateTimeHelper_Twig extends Twig_Extension
{
    public function getFilters()
    {
        return array(
            'datetime' => new Twig_Filter_Method($this, 'datetime',
                array('needs_environment' => true)),
        );
    }

    // This uses `strftime` which makes use of the locale. The format is not
    // compatible with the one of date() or DateTime::format().
    public function datetime(Twig_Environment $env, $date,
                             $format = "%B %e, %Y %H:%M", $timezone = null)
    {
        $date = twig_date_converter($env, $date, $timezone);

        return strftime($format, $date->getTimestamp());
    }

    public function getName()
    {
        return 'DateTimeHelper';
    }
}

$loader = new Twig_Loader_String();
$twig = new Twig_Environment($loader);

// Call the setlocale before you use the `datetime` in your templates.
// This only needs to be done once per request.
// If you already have a locale configured in your environment, 
// you can replace this with setlocale(LC_TIME, ""); - that way the
// locale of your environment is used.
setlocale(LC_TIME, "zh_CN.UTF-8");

// Add the extension to Twig like that:
$twig->addExtension(new DateTimeHelper_Twig());

$message = array('time' => time() * 1000);

// use the `datetime` filter with %a which gets replaced by the short weekday name of
// the current locale.
echo $twig->render('{{ (message.time/1000)|datetime("%m月%d日, 周%a") }}',
    array('message' => $message)), PHP_EOL;

This code shows 10月09日, 周三 on my system (after I installed the debian package locales-all ;-) ).

Of course, locales come with a list of restrictions you probably need to be aware of:

  • You have to use the correct locale (probably with UTF-8) and the locale you need has to be installed on all the systems which use your code.
  • Also this solution is not fully platform-independent (on windows setlocale works different/gives different results). Check out the PHP-manual of setlocale
  • It's easy to screw things up.

Using intl and the Twig-extensions

If you can use the intl extensions and the "Twig-extensions"-package, you have to use localizeddate instead of date:

// add the extension like that
$twig->addExtension(new Twig_Extensions_Extension_Intl());

$message = array('time' => time() * 1000);
echo $twig->render('{{ (message.time/1000)|localizeddate("none", "none", "zh", null, "MM月dd日, eee") }}', array('message' => $message)), PHP_EOL;

That code also shows 10月09日, 周三 - it even adds the 周-thingie automatically.

Of course, the date-format here is also different - check out the ICU user guide.



回答2:

You can try this code if the setlocale function cannot working on you system.

<?php
require_once dirname(__FILE__).'/vendor/autoload.php';

$loader = new Twig_Loader_String();
$twig   = new Twig_Environment($loader);

$twig->addFilter(new Twig_SimpleFilter('format_date', function($value) {
    $weekdays = array('日','一','二','三','四','五','六');

    return sprintf("%s, 周%s", date("m月d日"), $weekdays[date("w")]);
}));

echo $twig->render('{{ time_at | format_date }}', array(
    'time_at' => 1380813820000/1000
));


回答3:

I found a quick filter replace , here is the code snippet:

<div class="date"><span>{{ (create_time/1000)|date("m月d日,周D")|replace({'Mon':'一','Tue':'二','Wed':'三','Thu':'四','Fri':'五','Sat':'六','Sun':'日'}) }}</span></div>


标签: php date twig