mohamedsabil83/laravel-hijrian
mohamedsabil83/laravel-hijrian brings Hijri calendar support to Laravel. Convert Gregorian dates to Hijri and back, format and localize Islamic dates, and use convenient helpers to display Hijri dates throughout your Laravel applications.
composer require mohamedsabil83/laravel-hijrian. v4.3.0 adds Laravel 12 & 13 support; if you're still on Laravel 10/11, pin to an earlier 4.x that matches your framework version rather than assuming the newest tag is safe.config/hijrian.php (publish with php artisan vendor:publish --tag=hijrian-config — check the README for the exact tag), which controls locale/month-name output.Hijrian facade / service class, which is the main entry point.use Mohamedsabil83\Hijrian\Facades\Hijrian;
$hijri = Hijrian::toHijri(now()); // array/object with day, month, year, month name
$greg = Hijrian::toGregorian('1446-09-01');
php artisan tinker round-trip (toHijri then toGregorian) before wiring it into anything. That single check tells you the return shape, the accepted input formats (string vs. Carbon vs. DateTimeInterface), and how month names are localized in your app's current locale.Store Gregorian, render Hijri. Keep timestamp/date columns as normal Gregorian values so querying, sorting, and indexing keep working. Convert only at the presentation or report boundary.
// app/Models/Post.php
protected function publishedHijri(): Attribute
{
return Attribute::get(fn () => Hijrian::toHijri($this->published_at));
}
Blade rendering. Wrap conversion in a small helper or Blade directive/component so views never call the facade directly with raw strings:
{{ hijri($post->published_at) }} {{-- e.g. "12 Rabi' al-Awwal 1446" --}}
Keep the formatting logic (month-name style, ordinal suffixes, "AH" suffix) in one presenter class, since the package returns structured data rather than a single pre-formatted string.
Localized month names. Month names follow the app locale through the package's translation files. Set app.locale per request (or via middleware) for multilingual sites, and add a custom translation file if you need a dialect or spelling variant. Clear config:cache after touching config/hijrian.php.
Date-picker / form input. For admin forms that accept a Hijri date, take three separate inputs (year, month, day) or a masked YYYY-MM-DD, validate them, then convert to Gregorian once before persisting. Round-tripping user input through the converter on every keystroke is a common source of off-by-one-day bugs.
Reporting and grouping. Hijri month boundaries don't align with Gregorian ones, so GROUP BY MONTH(created_at) won't work. Fetch the range in SQL using Gregorian boundaries you computed in PHP, then bucket rows in a collection:
$rows = Order::whereBetween('created_at', [$start, $end])->get()
->groupBy(fn ($o) => Hijrian::toHijri($o->created_at)['month']);
Testing. The package is deterministic for a given input, so freeze time with Carbon::setTestNow() and assert exact conversion output. Add one test that pins a known date pair (e.g. 1 Muharram 1446) so a dependency bump that silently changes the underlying calculation algorithm fails loudly.
Integration tip: expose the converter behind your own thin interface (HijriConverter) bound in a service provider. That keeps the third-party facade out of your domain code and makes it trivial to swap implementations or mock it in tests.
Carbon instance in the app's timezone (config('app.timezone')) rather than a UTC string, or dates near midnight shift a day.echo it directly and don't assume ->format() exists; build your display string from the day/month/year/month-name fields.^9.5.2, CI action bumps). The functional surface looks unchanged, so upgrading from 4.2.0 should be low risk — but run your own conversion assertions, since the underlying calculation dependency could have shifted without a changelog entry.dd(Hijrian::toHijri($date)) to inspect the full component array; if the result looks shifted, compare against a known reference date pair before suspecting your code.How can I help you explore Laravel packages today?