Twig 文件中的 Symfony 日期到 Hijri 日期转换

Symfony Date to Hijri date conversion in twig file

在 symfony 模板中,我们可以使用像

这样的格式化程序
{{ news.created|date('Y-m-d') }}

我需要类似的回历日期转换工具。意思是我在公历中提供日期并将其转换为 twig 模板文件中的 hijri 可能类似于

{{ news.created|hijridate }}

我在论坛等上搜索了很多,但没有在 twig 模板中找到特别相关的内容。

在没有找到任何解决方案后,我制作了自己的树枝扩展。我正在粘贴它,希望它能帮助任何输入日期对象的人 {{ newsitem.created|hdate }} 输出是 الأربعاء 10 رمضان 1437 年

使用以下代码在src/AppBundle/Twig/HdateExtension.php中编写一个树枝扩展。

<?php
namespace AppBundle\Twig;

class HdateExtension extends \Twig_Extension
{

public function getFilters()
{
    return array(
      new \Twig_SimpleFilter('hdate', array($this, 'hdateConvert') )
    );
}


public function hdateConvert($date)
{

    if($date instanceof \DateTime){
        $dateDay = $date->format('N');
        $date->modify('+1 day');
        $year = $date->format('Y');
        $month = $date->format('m');
        $day = $date->format('d');
    }
    $dayH = array("الأثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت","الأحد");
    // actual calculation
    $newDate = $dayH[$dateDay-1]." ".HdateExtension::Greg2Hijri($day, $month, $year, true );
    return $newDate;
}
public function getName()
{
    return 'hdate_extension';
}

public function Greg2Hijri($day, $month, $year, $string = false)
{
    $day   = (int) $day;
    $month = (int) $month;
    $year  = (int) $year;

    if (($year > 1582) or (($year == 1582) and ($month > 10)) or (($year == 1582) and ($month == 10) and ($day > 14)))
    {
        $jd = HdateExtension::intPart((1461*($year+4800+HdateExtension::intPart(($month-14)/12)))/4)+HdateExtension::intPart((367*($month-2-12*(HdateExtension::intPart(($month-14)/12))))/12)-
            HdateExtension::intPart( (3* (HdateExtension::intPart(  ($year+4900+    HdateExtension::intPart( ($month-14)/12)     )/100)    )   ) /4)+$day-32075;
    }
    else
    {
        $jd = 367*$year-HdateExtension::intPart((7*($year+5001+HdateExtension::intPart(($month-9)/7)))/4)+HdateExtension::intPart((275*$month)/9)+$day+1729777;
    }

    $l = $jd-1948440+10632;
    $n = HdateExtension::intPart(($l-1)/10631);
    $l = $l-10631*$n+354;
    $j = (HdateExtension::intPart((10985-$l)/5316))*(HdateExtension::intPart((50*$l)/17719))+(HdateExtension::intPart($l/5670))*(HdateExtension::intPart((43*$l)/15238));
    $l = $l-(HdateExtension::intPart((30-$j)/15))*(HdateExtension::intPart((17719*$j)/50))-(HdateExtension::intPart($j/16))*(HdateExtension::intPart((15238*$j)/43))+29;

    $month = HdateExtension::intPart((24*$l)/709);
    $day   = $l-HdateExtension::intPart((709*$month)/24);
    $year  = 30*$n+$j-30;
    $mname = array("محرّم","صفر","ربيع الأوّل"," ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوّال","ذو القعدة","ذو الحجّة");
    $date = array();
    $date['year']  = $year;
    $date['month'] = $mname[$month-1];
    $month = $mname[$month-1];
    $date['day']   = $day;

    if (!$string)
        return $date;
    else
        return     "{$day}  {$month}  {$year}  هـ ";
}
public function intPart($float)
{
    if ($float < -0.0000001)
        return ceil($float - 0.0000001);
    else
        return floor($float + 0.0000001);
}

}

然后在services.yml文件中添加以下内容

  app.twig_extension:
  class: AppBundle\Twig\HdateExtension
  public: false
  tags:
      - { name: twig.extension }

感谢您的代码, symfony 5:

<?php

namespace App\Twig;

use Exception;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;

class HdateExtension extends AbstractExtension {
    /**
     * @return TwigFilter[]
     */
    public function getFilters(): array {
        return [
            new TwigFilter(
                'hdate', [
                $this, 'hdateConvert'
            ])
        ];
    }

    /**
     * @param $arg
     * @return string
     * @throws Exception
     */
    public function hdateConvert($arg): string {
        if ($arg instanceof \DateTime) {
            $dayNumber = $arg->format('N');
            $arg->modify('+1 day');
            $year = $arg->format('Y');
            $month = $arg->format('n');
            $day = $arg->format('j');

            $dayH = [
                "الأثنين",
                "الثلاثاء",
                "الأربعاء",
                "الخميس",
                "الجمعة",
                "السبت",
                "الأحد"
            ];

            return $dayH[$dayNumber - 1] . " " . HdateExtension::Greg2Hijri($day, $month, $year);
        }

        throw new Exception('Invalid date');
    }

    /**
     * @return string
     */
    public function getName(): string {
        return 'hdate_extension';
    }

    /**
     * @param int $day
     * @param int $month
     * @param int $year
     * @return string
     */
    public function Greg2Hijri(int $day, int $month, int $year): string {
        if (
            ($year > 1582) or
            (($year == 1582) and ($month > 10)) or
            (($year == 1582) and ($month == 10) and ($day > 14))
        ) {
            $jd = HdateExtension::intPart((1461 * ($year + 4800 + HdateExtension::intPart(($month - 14) / 12))) / 4) + HdateExtension::intPart((367 * ($month - 2 - 12 * (HdateExtension::intPart(($month - 14) / 12)))) / 12) -
                HdateExtension::intPart((3 * (HdateExtension::intPart(($year + 4900 + HdateExtension::intPart(($month - 14) / 12)) / 100))) / 4) + $day - 32075;
        } else {
            $jd = 367 * $year - HdateExtension::intPart((7 * ($year + 5001 + HdateExtension::intPart(($month - 9) / 7))) / 4) + HdateExtension::intPart((275 * $month) / 9) + $day + 1729777;
        }

        $l = $jd - 1948440 + 10632;
        $n = HdateExtension::intPart(($l - 1) / 10631);
        $l = $l - 10631 * $n + 354;
        $j = (HdateExtension::intPart((10985 - $l) / 5316)) * (HdateExtension::intPart((50 * $l) / 17719)) + (HdateExtension::intPart($l / 5670)) * (HdateExtension::intPart((43 * $l) / 15238));
        $l = $l - (HdateExtension::intPart((30 - $j) / 15)) * (HdateExtension::intPart((17719 * $j) / 50)) - (HdateExtension::intPart($j / 16)) * (HdateExtension::intPart((15238 * $j) / 43)) + 29;

        $month = HdateExtension::intPart((24 * $l) / 709);
        $day = $l - HdateExtension::intPart((709 * $month) / 24);
        $year = 30 * $n + $j - 30;
        $mname = [
            "محرّم",
            "صفر",
            "ربيع الأوّل",
            " ربيع الثاني",
            "جمادى الأولى",
            "جمادى الثانية",
            "رجب",
            "شعبان",
            "رمضان",
            "شوّال",
            "ذو القعدة",
            "ذو الحجّة"
        ];

        return "{$day}  {$mname[$month - 1]}  {$year}  هـ ";
    }

    /**
     * @param $float
     * @return false|float
     */
    private function intPart($float) {
        if ($float < -0.0000001)
            return ceil($float - 0.0000001);
        else
            return floor($float + 0.0000001);
    }
}