hekmatinasser/verta
Verta provides Jalali (Solar) and Gregorian date conversion plus handy date/time helpers. Extends PHP DateTime, works with Carbon, supports formatting, localization, validation, boundaries, and human-readable diffs—ideal for Laravel and PHP apps needing Persian dates.
Install via Composer:
composer require hekmatinasser/verta
First Use Case: Replace Gregorian dates in your app with Jalali equivalents.
// Get current Jalali date
$jalaliDate = verta(); // Returns "1401-05-24 00:00:00"
// Convert Gregorian Carbon instance to Jalali
$gregorianDate = now();
$jalaliDate = $gregorianDate->toJalali(); // Returns "1401-05-24 00:00:00"
// Parse Jalali string into Verta instance
$vertaInstance = Verta::parse('1401-05-24 14:12:32');
Where to Look First:
verta() helper for quick instantiation.toJalali()/toCarbon() for bidirectional conversions.Date Conversion Pipeline:
// API Request → Gregorian → Jalali → Store/Display
$gregorianInput = request('date');
$jalaliDate = verta($gregorianInput)->formatJalaliDatetime();
Validation Integration:
// Form validation rule
$request->validate([
'birthday' => 'required|jdate_before_equal:today',
]);
Localization-Aware Display:
// Set locale and format
Verta::setLocale('fa');
$formattedDate = verta()->formatWord('l dS F'); // "دوشنبه بیست و چهارم مرداد"
Eloquent Models: Use accessors/mutators for Jalali date fields:
public function getJalaliDateAttribute()
{
return verta($this->attributes['created_at'])->formatJalaliDatetime();
}
Carbon Compatibility: Leverage existing Carbon methods with Jalali awareness:
$jalaliDate = verta()->addDays(7)->subHours(2); // Works like Carbon
Blade Directives: Create a custom Blade directive for consistent formatting:
Blade::directive('jalali', function ($expression) {
return "<?php echo verta({$expression})->formatJalaliDatetime(); ?>";
});
Usage: @jalali($post->created_at)
Testing: Mock verta() in tests using the Verta facade:
Verta::shouldReceive('parse')->andReturn(Verta::create('1401-01-01'));
| Use Case | Pattern |
|---|---|
| User Input Handling | verta(request('date'))->isValid() |
| Scheduling | verta()->addWeeks(2)->startOfDay() |
| Age Calculation | verta()->diffInYears($user->birthday) |
| Localized Notifications | verta($event->date)->formatWord('l jS F') |
| API Responses | return verta($order->created_at)->format('Y/m/d H:i'); |
Timezone Mismatches:
Asia/Tehran) is set in config/app.php if time-sensitive operations are involved.verta('2024-01-05', 'Asia/Tehran');
Leap Year Edge Cases:
Verta::isLeapYear() to validate or adjust logic:
if (Verta::isLeapYear($year)) { /* Handle leap year logic */ }
Carbon Version Conflicts:
composer.json:
"require": {
"carbon/carbon": "^2.60"
}
Database Storage:
1401-01-01 ≠ Gregorian 2022-03-21).// Migration
$table->dateTime('created_at');
// Model
public function getJalaliCreatedAtAttribute()
{
return verta($this->created_at)->formatJalaliDatetime();
}
Localization Quirks:
en if needed:
Verta::setLocale('ar'); // May throw if unsupported
verta('invalid-date')->isValid(); // Returns false
$date = verta();
dump($date->year, $date->month, $date->day); // Debug components
$carbon = now();
$jalali = verta();
dump($carbon->diffInDays($jalali->toCarbon())); // Should be ~0 for same date
Custom Formatters: Extend the formatter by creating a new class:
use Verta\Verta;
class CustomFormatter {
public static function fiscalYear(Verta $date)
{
return $date->year + 1300; // Example: Fiscal year logic
}
}
Validation Rules:
Add custom rules to AppServiceProvider:
use Illuminate\Support\Facades\Validator;
Validator::extend('jdate_after_today', function ($attribute, $value, $parameters) {
return verta($value)->gte(verta());
});
Carbon Extensions: Add Jalali methods to Carbon globally:
Carbon::macro('toJalali', function () {
return verta($this)->formatJalaliDatetime();
});
Localization Overrides:
Override month/day names in config/verta.php:
'locales' => [
'fa' => [
'months' => ['فروردین', 'اردیبهشت', /* ... */],
'days' => ['شنبه', 'یکشنبه', /* ... */],
],
],
$cachedDate = verta($user->birthday);
$dates = collect($orders)->map(fn ($order) => verta($order->created_at));
$isLeap = Verta::isLeapYear($year); // Cache result
config/verta.php:
'default_locale' => 'fa',
'carbon_integration' => false,
'strict' => true, // Throws \InvalidArgumentException on invalid input
How can I help you explore Laravel packages today?