Skip to content
Devix Open Source

Guide

Getting started

composer require devix-labs/laravel-hijri
php artisan vendor:publish --tag=hijri-config   # optional

In Blade

<p>Issued @hijri($invoice->created_at)</p>
{{-- 1 Rabi' al-Thani 1448 AH --}}

<p>@hijri($invoice->created_at, 'yyyy-MM-dd')</p>
{{-- 1448-04-01 --}}

The pattern and language come from config/hijri.php, and the language follows your application's locale unless you set one — so an Arabic page prints Arabic months.

On a Carbon instance

$invoice->created_at->toHijri();              // a HijriDate
$invoice->created_at->toHijri()->year;        // 1448
$invoice->created_at->hijriFormat();          // 1 Rabi' al-Thani 1448 AH
$invoice->created_at->hijriFormat('d MMMM', ['locale' => 'ar', 'numerals' => 'arab']);

Through the facade

use Devix\Hijri\Laravel\Facades\Hijri;
use Devix\Hijri\PlainDate;

Hijri::toHijri('2026-09-12');
Hijri::fromHijri(new PlainDate(1448, 10, 1))->gregorian->iso();   // 2027-03-09
Hijri::today(['timeZone' => 'Asia/Dubai']);
Hijri::daysInMonth(1448, 9);                                      // 29 or 30, from the table
Hijri::addMonths(new PlainDate(1448, 12, 30), 1);                 // clamps to the next month
Hijri::diffDays(new PlainDate(1448, 1, 1), new PlainDate(1449, 1, 1));

Ramadan and the Eids

$ramadan = Hijri::ramadan(1448);
// ['start' => HijriDate(2027-02-08), 'end' => HijriDate(2027-03-08), 'days' => 29]

collect(Hijri::events(1448, ['locale' => 'ar']))->firstWhere('key', 'eid-al-fitr');
// ['key' => 'eid-al-fitr', 'name' => 'عيد الفطر', 'gregorian' => PlainDate(2027-03-09), 'inDays' => 178]

Nine dates, with a countdown in inDays. They are calendar dates: in most countries the moon decides and the announcement can move a day, so say "expected" in your interface.

When your country is a day out

// config/hijri.php
'offset' => 1,

Or per call: Hijri::toHijri($date, ['offset' => 1]). The offset applies both ways, so conversions stay consistent.

Storing Hijri dates

Store the Gregorian date — it is unambiguous and sorts — and convert for display:

protected function casts(): array
{
    return ['issued_on' => 'date'];
}

// In the template
@hijri($contract->issued_on)

If you must store the Hijri date, store year, month and day as integers rather than a string, and keep the offset you used beside them.

Checking you can trust a date

Hijri::toHijri('2026-09-12')->exact;                         // true — from the published table
Hijri::fromHijri(new PlainDate(1700, 1, 1))->exact;          // false — arithmetic beyond the table

Show that distinction when the date matters. Nothing else in PHP tells you.

Updated 15 Sep 2026