PHPackages                             hpakdaman/multicarbon - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. hpakdaman/multicarbon

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

hpakdaman/multicarbon
=====================

Multi-calendar extension for Carbon — Jalali (Solar Hijri), Hijri (Islamic Lunar), and Gregorian support.

v1.0.0(4mo ago)458MITPHPPHP ^8.1

Since Feb 14Pushed 1mo agoCompare

[ Source](https://github.com/hpakdaman/multicarbon)[ Packagist](https://packagist.org/packages/hpakdaman/multicarbon)[ RSS](/packages/hpakdaman-multicarbon/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (2)Versions (2)Used By (0)

MultiCarbon
===========

[](#multicarbon)

**A multi-calendar extension for [Carbon](https://carbon.nesbot.com/) — seamlessly work with Jalali (Solar Hijri), Hijri (Islamic Lunar), and Gregorian calendars using the same familiar Carbon API.**

[![License: MIT](https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667)](LICENSE)[![PHP Version](https://camo.githubusercontent.com/ef363a5a30025ffef1857918c40fa01e97f03929e5f87d12a14bf334a7de9220/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e312d3838393242462e737667)](https://php.net)

> Part of **[UnfoldCMS](https://unfoldcms.com)** — the open, self-hosted CMS for developers. MultiCarbon powers the multi-calendar date handling behind UnfoldCMS.

---

Why MultiCarbon?
----------------

[](#why-multicarbon)

Carbon is the gold standard for date/time in PHP. But if you work with Persian (Jalali) or Islamic (Hijri) calendars, you've had to choose between limited wrappers or entirely separate libraries that throw away everything Carbon gives you.

**MultiCarbon *is* Carbon.** It extends `Carbon\Carbon` directly, which means every single Carbon feature — timezone handling, diffing, serialization, immutability, macros, Laravel integration — works exactly as you expect. You don't lose anything. You just gain Jalali and Hijri support on top.

Every method you already know (`format()`, `addMonths()`, `diffForHumans()`, `startOfMonth()`, `addDays()`, `isPast()`, ...) works natively in your calendar of choice. Switch between calendars on the same instance, and the underlying timestamp never changes.

```
// Create a date in Jalali calendar — the most natural way
$carbon = MultiCarbon::createJalali(1404, 1, 1); // Nowruz 1404

echo $carbon->format('Y/m/d');                   // "1404/01/01"
echo $carbon->format('l j F Y');                  // "جمعه 1 فروردین 1404"

// Switch between calendars on the same instance
echo $carbon->hijri()->format('Y/m/d');          // "1446/08/21"
echo $carbon->gregorian()->format('Y/m/d');      // "2025/03/21"

// Or start from a Gregorian string — works seamlessly
echo (new MultiCarbon('2025-03-21'))->jalali()->format('Y/m/d'); // "1404/01/01"
```

### It's Just Carbon

[](#its-just-carbon)

Because MultiCarbon extends Carbon, every Carbon method works out of the box — even in Jalali or Hijri mode:

```
$date = MultiCarbon::createJalali(1404, 6, 15, 14, 30, 0);

// All of Carbon's methods work — you lose nothing
$date->addDays(10);                    // add 10 days (Carbon native)
$date->addMonths(2);                   // add 2 Jalali months (calendar-aware)
$date->isPast();                       // true/false
$date->isWeekend();                    // Friday detection (Iranian week)
$date->diffForHumans();                // "۳ ماه پیش" (localized Persian)
$date->getTimestamp();                 // Unix timestamp — always correct
$date->timezone('Asia/Tehran');        // Carbon timezone support
$date->toIso8601String();             // ISO output via Carbon
$date->copy()->startOfMonth();        // 1404/08/01 00:00:00

// Switch to Gregorian anytime — full Carbon, no restrictions
$date->gregorian()->format('Y-m-d');  // "2025-11-05"

// Pass it anywhere that expects Carbon — it just works
function logDate(Carbon\Carbon $date) { /* ... */ }
logDate($date); // MultiCarbon IS Carbon
```

Features
--------

[](#features)

- **Full Carbon compatibility** — extends `Carbon\Carbon`, so every Carbon method works out of the box
- **Three calendar systems** — Jalali (Solar Hijri), Hijri Qamari (Islamic Lunar), and Gregorian
- **Fluent calendar switching** — `->jalali()`, `->hijri()`, `->gregorian()` on any instance
- **Calendar-aware arithmetic** — `addMonths()`, `addYears()`, `startOfMonth()`, `endOfYear()` respect calendar boundaries
- **Localized output** — Persian and Arabic month names, weekday names, AM/PM, and "diff for humans"
- **Digit display** — Latin, Farsi (`۱۲۳۴`), or Arabic-Indic (`١٢٣٤`) digits globally
- **Iranian week** — Saturday as first day, Friday as weekend
- **Laravel integration** — auto-discovery, Facade, Blade directives (`@jalali`, `@hijri`, `@jdate`, `@hdate`)
- **Global helpers** — `jdate()`, `hdate()`, `multicarbon()` available everywhere
- **Zero dependencies** beyond Carbon itself

Installation
------------

[](#installation)

```
composer require hpakdaman/multicarbon
```

**Requirements:** PHP 8.1+ and Carbon 2.x or 3.x.

### Laravel

[](#laravel)

The package auto-discovers its ServiceProvider and Facade. No manual registration needed.

Quick Start
-----------

[](#quick-start)

### Create Dates

[](#create-dates)

```
use MultiCarbon\MultiCarbon;

// From now
$date = new MultiCarbon();

// From a Gregorian string (defaults to Jalali mode)
$date = new MultiCarbon('2025-03-21');
echo $date->year;   // 1404
echo $date->month;  // 1
echo $date->day;    // 1

// Create directly in Jalali
$date = MultiCarbon::createJalali(1404, 1, 1, 12, 0, 0);

// Create directly in Hijri
$date = MultiCarbon::createHijri(1446, 9, 1);
```

### Switch Calendars

[](#switch-calendars)

```
$date = new MultiCarbon('2025-03-21');

// Fluent switching — same underlying moment, different calendar view
echo $date->jalali()->format('Y/m/d');     // "1404/01/01"
echo $date->hijri()->format('Y/m/d');      // "1446/08/21"
echo $date->gregorian()->format('Y/m/d');  // "2025/03/21"

// The timestamp never changes
echo $date->jalali()->timestamp === $date->gregorian()->timestamp;  // true
```

### Format Dates

[](#format-dates)

All of PHP's date format characters are supported:

```
$date = MultiCarbon::createJalali(1404, 1, 15, 14, 30, 0);

$date->format('Y-m-d H:i:s');  // "1404-01-15 14:30:00"
$date->format('l j F Y');      // "شنبه 15 فروردین 1404"
$date->format('D, M j, Y');    // "ش, فرو 15, 1404"

// Hijri formatting
$hijri = MultiCarbon::createHijri(1446, 9, 1);
$hijri->format('F Y');          // "رمضان 1446"
```

### Date Arithmetic

[](#date-arithmetic)

Month and year arithmetic respects calendar boundaries:

```
$date = MultiCarbon::createJalali(1404, 6, 31);  // Shahrivar 31

$date->addMonth();
echo $date->format('Y/m/d');  // "1404/07/30" — clamped to Mehr's max (30 days)

$date = MultiCarbon::createJalali(1403, 12, 30);  // Esfand 30 (leap year)
$date->addYear();
echo $date->format('Y/m/d');  // "1404/12/29" — clamped (1404 is not leap)
```

### Boundary Methods

[](#boundary-methods)

```
$date = MultiCarbon::createJalali(1404, 6, 15, 14, 30, 0);

$date->startOfMonth();  // 1404/06/01 00:00:00
$date->endOfMonth();    // 1404/06/31 23:59:59
$date->startOfYear();   // 1404/01/01 00:00:00
$date->endOfYear();     // 1404/12/29 23:59:59

$date->startOfWeek();   // Previous Saturday 00:00:00
$date->endOfWeek();     // Next Friday 23:59:59
```

### Comparison

[](#comparison)

```
$a = MultiCarbon::createJalali(1404, 1, 1);
$b = MultiCarbon::createJalali(1404, 1, 25);

$a->isSameMonth($b);   // true
$a->isSameDay($b);     // false
$a->lessThan($b);      // true
$a->diffInDays($b);    // 24
```

### Diff for Humans

[](#diff-for-humans)

Localized in Persian and Arabic:

```
// Persian
$date = MultiCarbon::createJalali(1403, 1, 1);
echo $date->diffForHumans();  // "1 سال پیش"

// Arabic
$date = MultiCarbon::createHijri(1445, 1, 1);
echo $date->diffForHumans();  // "منذ 1 سنة"
```

### Digit Display

[](#digit-display)

```
MultiCarbon::setDigitsType(MultiCarbon::DIGITS_FARSI);
echo MultiCarbon::createJalali(1404, 1, 1)->format('Y/m/d');
// "۱۴۰۴/۰۱/۰۱"

MultiCarbon::setDigitsType(MultiCarbon::DIGITS_ARABIC);
echo MultiCarbon::createHijri(1446, 9, 1)->format('Y/m/d');
// "١٤٤٦/٠٩/٠١"

MultiCarbon::setDigitsType(MultiCarbon::DIGITS_LATIN);  // default
```

### Conversion &amp; Interop

[](#conversion--interop)

```
use Carbon\Carbon;
use MultiCarbon\MultiCarbon;

// From Carbon
$carbon = Carbon::parse('2025-03-21');
$mc = MultiCarbon::fromCarbon($carbon);  // Jalali mode by default

// From DateTime
$dt = new \DateTime('2025-03-21');
$mc = MultiCarbon::fromDateTime($dt);

// Back to Carbon
$carbon = $mc->toCarbon();

// Parse a calendar-specific string
$mc = MultiCarbon::parseFormat('Y/m/d', '1404/01/15');  // Jalali
$mc = MultiCarbon::parseFormat('Y/m/d', '1446/07/15', CalendarMode::HIJRI);

// To array
$mc->toArray();
// ['year' => 1404, 'month' => 1, 'day' => 15, 'hour' => 0, 'minute' => 0, 'second' => 0]
```

### Global Helpers

[](#global-helpers)

```
// Jalali
jdate();                  // MultiCarbon instance in Jalali mode
jdate('Y/m/d');           // "1404/01/15"
jdate('Y/m/d', $timestamp);

// Hijri
hdate();                  // MultiCarbon instance in Hijri mode
hdate('Y/m/d');           // "1446/08/15"

// General
multicarbon();            // MultiCarbon instance
```

### Laravel Blade Directives

[](#laravel-blade-directives)

```
{{-- Current Jalali date --}}
@jdate('Y/m/d H:i:s')

{{-- Current Hijri date --}}
@hdate('Y/m/d')

{{-- Convert a variable --}}
@jalali($user->created_at, 'Y/m/d')
@hijri($post->published_at, 'Y/m/d')
```

API Reference
-------------

[](#api-reference)

### Calendar Mode

[](#calendar-mode)

MethodDescription`->jalali()`Switch to Jalali (Solar Hijri) mode`->hijri()`Switch to Hijri (Islamic Lunar) mode`->gregorian()`Switch to Gregorian mode`->isJalali()`Check if in Jalali mode`->isHijri()`Check if in Hijri mode`->isGregorian()`Check if in Gregorian mode`->getCalendar()`Get current calendar mode string### Factory Methods

[](#factory-methods)

MethodDescription`MultiCarbon::createJalali($y, $m, $d, $h, $min, $s, $tz)`Create from Jalali components`MultiCarbon::createHijri($y, $m, $d, $h, $min, $s, $tz)`Create from Hijri components`MultiCarbon::fromCarbon($carbon, $calendar)`Create from a Carbon instance`MultiCarbon::fromDateTime($dateTime, $calendar)`Create from a DateTime instance`MultiCarbon::parseFormat($format, $date, $calendar, $tz)`Parse a calendar-specific date string### Getters

[](#getters)

Property / MethodDescription`->year`, `->getYear()`Year in active calendar`->month`, `->getMonth()`Month in active calendar`->day`, `->getDay()`Day in active calendar`->monthName`, `->getMonthName()`Localized month name`->dayName`Localized weekday name`->dayOfWeek`, `->getDayOfWeek()`Day of week (Saturday=0)`->dayOfYear`, `->getDayOfYear()`Day of year (1-indexed)`->daysInMonth`, `->getMonthDays()`Days in current month`->quarter`Quarter (1-4)`->isLeapYear()`Is the current year a leap year?### Arithmetic

[](#arithmetic)

MethodDescription`->addMonths($n)` / `->subMonths($n)`Add/subtract months (calendar-aware)`->addYears($n)` / `->subYears($n)`Add/subtract years (calendar-aware)`->addDays($n)` / `->subDays($n)`Add/subtract days (inherited from Carbon)`->addWeekdays($n)` / `->subWeekdays($n)`Add/subtract weekdays (skips weekends)### Boundaries

[](#boundaries)

MethodDescription`->startOfMonth()` / `->endOfMonth()`Calendar-aware month boundaries`->startOfYear()` / `->endOfYear()`Calendar-aware year boundaries`->startOfWeek()` / `->endOfWeek()`Week boundaries (Saturday-Friday)How It Works
------------

[](#how-it-works)

MultiCarbon extends Carbon and intercepts property access (`year`, `month`, `day`) and key methods (`format()`, `setDate()`, `addMonths()`, etc.). It uses `debug_backtrace()` to detect whether a method was called by user code or by Carbon's internal engine:

- **User code calls** `$date->year` → returns the value in the active calendar (Jalali/Hijri)
- **Carbon internally calls** `$this->year` → returns Gregorian so parent logic works correctly

This means all of Carbon's existing methods (diffing, timezone handling, serialization) continue to work without modification. The conversion only happens at the boundary between your code and Carbon.

Testing
-------

[](#testing)

```
composer install
./vendor/bin/phpunit
```

Part of UnfoldCMS
-----------------

[](#part-of-unfoldcms)

MultiCarbon is built and maintained as part of **[UnfoldCMS](https://unfoldcms.com)** — an open, self-hosted CMS for developers and teams. UnfoldCMS uses MultiCarbon for all of its Jalali, Hijri, and Gregorian date handling.

If you find MultiCarbon useful, check out the full CMS at **[unfoldcms.com](https://unfoldcms.com)**.

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) for details.

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance86

Actively maintained with recent releases

Popularity15

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

139d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ab8fe02dfb49d4f556126fa0607f426ed1944e51a92b4180bc7beeaecc914ce6?d=identicon)[iraitc](/maintainers/iraitc)

---

Top Contributors

[![hpakdaman](https://avatars.githubusercontent.com/u/9606809?v=4)](https://github.com/hpakdaman "hpakdaman (4 commits)")

---

Tags

phplaravelcarboncalendarJalalipersianshamsihijri

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/hpakdaman-multicarbon/health.svg)

```
[![Health](https://phpackages.com/badges/hpakdaman-multicarbon/health.svg)](https://phpackages.com/packages/hpakdaman-multicarbon)
```

###  Alternatives

[fisharebest/ext-calendar

Implementation of the Arabic (Hijri), French, Gregorian, Jewish, Julian and Persian (Jalali) calendars. Also provides a replacement for the PHP ext/calendar extension.

36513.6k11](/packages/fisharebest-ext-calendar)[wilianx7/php-recurring

PHP library for generating recurring dates, schedules, and repeated task recurrences.

1050.7k](/packages/wilianx7-php-recurring)[p3ym4n/jdate

Date converter from Jalali to Georgian and vice versa. It has Carbon instance inside and it's Laravel friendly.

101.8k2](/packages/p3ym4n-jdate)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
