If you build software for 85+ million Persian speakers, you need Jalali (Solar Hijri) dates. And if you do it in PHP, you've probably met the usual suspects: libraries built a decade ago, strftime() calls that PHP 8.1 deprecated, mutable date objects that cause spooky action-at-a-distance in queue workers, and holiday lists you have to maintain by hand.

I built ParsiDate to fix that for my own projects. It's now at v1.1.0, MIT licensed, with 136 passing tests:

composer require mahdyaralipor/parsidate 

Design decisions

1. Immutable by default. Every arithmetic method returns a new instance:

$date = ParsiDate::create(1403, 1, 1); $later = $date->addDays(10); // $date is untouched 

If you've ever debugged a Carbon object mutated three call frames away, you know why this matters.

2. Zero dependencies. composer.json requires exactly one thing: php: ^8.1. No Carbon, no framework, no polyfills. It works in Laravel, Symfony, WordPress, or a bare script.

3. Holidays are data, not your problem. Official Iranian public holidays (1400–1406, verified date-by-date against the official calendar) ship inside the package, with an API for variable holidays:

$date->isHoliday(); // true on Nowruz $date->holidayName(); // "جشن نوروز" $date->addWorkdays(5); // skips Fridays + public holidays $date->workdaysUntil($other); 

4. Periods are iterable. Date ranges are first-class:

$period = ParsiPeriod::ofMonth(1403, 1); $period->countWorkdays(); $period->overlap($other); // ParsiPeriod|null $period->splitByDays(7); // weekly chunks foreach ($period->fridays() as $friday) { echo $friday->format('Y/m/d'); } 

5. Persian digits everywhere. Parsing and formatting both understand ۰۱۲۳۴۵۶۷۸۹, because real user input uses them:

ParsiDate::parse('۱۴۰۳/۰۶/۱۵'); $date->formatPersian('Y/m/d'); // ۱۴۰۳/۰۶/۱۵ 

6. Hijri conversion included. $date->toHijri() returns a value object with Arabic + Latin month names and array/JSON output. One honest caveat, documented in the README: it uses the tabular (arithmetic) calendar, so it can differ ±1–2 days from moon-sighting calendars.

What's next

  • Recurring events / RRULE-style helpers
  • More calendar systems on request
  • Framework bridges (a Laravel service provider is the most requested)

Repo: https://github.com/mahdyaralipor/parsidate

If you work with Jalali dates in production, I'd love to hear what your current setup is and where it hurts — that's what shapes the roadmap. And if it's useful, a ⭐ helps others find it.