morilog/jalali
morilog/jalali provides a fast, human-friendly Jalali (Persian) calendar API for PHP/Laravel. Convert and format dates, manipulate and compare date/times via the immutable Jalalian class, with helpers like jdate(), Carbon support, and “ago” relative output.
Installation
composer require morilog/jalali:^3.5.0
Laravel 5.5+ auto-discovers the service provider (Morilog\Jalali\JalalianizatorServiceProvider).
Basic Usage Convert a Carbon instance to Jalali with explicit type safety:
use Carbon\Carbon;
use Morilog\Jalali\Jalalianizator;
$carbonDate = Carbon::now();
$jalaliDate = Jalalianizator::jalali($carbonDate); // "1403/10/15" (example)
First Use Case: Displaying Jalali Dates In Blade:
{{ Carbon\Carbon::now()->jalali() }}
Or via helper (if configured):
jalali_date($carbonDate); // Now handles nullable inputs gracefully
Date Conversion with Null Safety
$jalali = Carbon::now()->jalali(); // "1403/10/15"
$gregorian = Jalalianizator::gregorian($jalali); // Carbon instance
$nullableJalali = Jalalianizator::jalali(null); // No error (returns null)
Timezone Handling
DateTimeZone (now nullable):
$jalali = Jalalianizator::jalali($carbonDate, null); // Uses Carbon's timezone
$jalali = Jalalianizator::jalali($carbonDate, new DateTimeZone('Asia/Tehran'));
Database Integration
$user->birthdate_jalali = $user->birthdate?->jalali(); // Null-safe chaining
'date' => 'nullable|date|after:1300/01/01', // Jalali format
Localization
Jalalianizator::setLocale([
'months' => ['فروردین', 'اردیبهشت', ...],
'days' => ['شنبه', 'یکشنبه', ...],
]);
API Responses
return response()->json([
'event_date' => $event->date?->jalali('Y-m-d'),
]);
Nullable Parameter Handling
null for Carbon/DateTime inputs:
Jalalianizator::jalali(null); // Returns null (no error)
Jalalianizator::gregorian(null); // Returns null
null returns:
$date = $model->date?->jalali(); // Safe chaining
Timezone Confusion
DateTimeZone if needed:
$jalali = Jalalianizator::jalali($carbonDate, new DateTimeZone('Asia/Tehran'));
null is passed.Database Queries
// ❌ Bad: WHERE jalali_date = '1403/10/15'
// ✅ Good: WHERE gregorian_date = '2024-12-26'
Edge Cases in Validation
'date' => 'nullable|date_format:Y/m/d|after:1300/01/01' // Jalali format
Performance
$jalaliDates = collect($events)->map(fn ($e) => $e->date?->jalali());
dd(Jalalianizator::jalali(null), Jalalianizator::gregorian('1403/10/15'));
$jalali = Jalalianizator::jalali($carbonDate, new DateTimeZone('UTC'));
Custom Formatters
Carbon::macro('jalaliShort', function () {
return $this?->jalali('Y/m/d');
});
Database Casts
class JalaliDateAttribute extends Attribute {
public function get($model) {
return $model->{$this->name}?->jalali();
}
}
Testing
$this->assertNull(Jalalianizator::jalali(null));
Carbon::setTestNow(Jalalianizator::gregorian('1400/01/01'));
Laravel Scout
$model->searchableAs('event_date')->attributesToSearch(['date']);
// In results:
$event->date?->jalali();
How can I help you explore Laravel packages today?