Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Jalali Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

First Steps

  1. Installation

    composer require morilog/jalali:^3.5.0
    

    Laravel 5.5+ auto-discovers the service provider (Morilog\Jalali\JalalianizatorServiceProvider).

  2. 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)
    
  3. 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
    

Implementation Patterns

Core Workflows

  1. Date Conversion with Null Safety

    • Carbon ↔ Jalali (explicitly nullable parameters):
      $jalali = Carbon::now()->jalali(); // "1403/10/15"
      $gregorian = Jalalianizator::gregorian($jalali); // Carbon instance
      $nullableJalali = Jalalianizator::jalali(null); // No error (returns null)
      
  2. Timezone Handling

    • Explicitly pass DateTimeZone (now nullable):
      $jalali = Jalalianizator::jalali($carbonDate, null); // Uses Carbon's timezone
      $jalali = Jalalianizator::jalali($carbonDate, new DateTimeZone('Asia/Tehran'));
      
  3. Database Integration

    • Storing Jalali Dates:
      $user->birthdate_jalali = $user->birthdate?->jalali(); // Null-safe chaining
      
    • Validation (unchanged, but now safer with nullable inputs):
      'date' => 'nullable|date|after:1300/01/01', // Jalali format
      
  4. Localization

    • Override display names (unchanged):
      Jalalianizator::setLocale([
          'months' => ['فروردین', 'اردیبهشت', ...],
          'days' => ['شنبه', 'یک‌شنبه', ...],
      ]);
      
  5. API Responses

    • Format dates with null checks:
      return response()->json([
          'event_date' => $event->date?->jalali('Y-m-d'),
      ]);
      

Gotchas and Tips

Common Pitfalls

  1. Nullable Parameter Handling

    • New: Methods now explicitly accept null for Carbon/DateTime inputs:
      Jalalianizator::jalali(null); // Returns null (no error)
      Jalalianizator::gregorian(null); // Returns null
      
    • Legacy Code: Ensure older code handles null returns:
      $date = $model->date?->jalali(); // Safe chaining
      
  2. Timezone Confusion

    • Fix: Explicitly pass DateTimeZone if needed:
      $jalali = Jalalianizator::jalali($carbonDate, new DateTimeZone('Asia/Tehran'));
      
    • Default: Uses Carbon’s timezone if null is passed.
  3. Database Queries

    • Unchanged: Still avoid storing Jalali dates directly. Convert to Gregorian for queries:
      // ❌ Bad: WHERE jalali_date = '1403/10/15'
      // ✅ Good: WHERE gregorian_date = '2024-12-26'
      
  4. Edge Cases in Validation

    • Nullable Validation:
      'date' => 'nullable|date_format:Y/m/d|after:1300/01/01' // Jalali format
      
  5. Performance

    • Unchanged: Cache converted dates in loops:
      $jalaliDates = collect($events)->map(fn ($e) => $e->date?->jalali());
      

Debugging Tips

  • Verify Nullable Conversions:
    dd(Jalalianizator::jalali(null), Jalalianizator::gregorian('1403/10/15'));
    
  • Check Timezone Overrides: If results are unexpected, explicitly set the timezone:
    $jalali = Jalalianizator::jalali($carbonDate, new DateTimeZone('UTC'));
    

Extension Points

  1. Custom Formatters

    • Extend with null safety:
      Carbon::macro('jalaliShort', function () {
          return $this?->jalali('Y/m/d');
      });
      
  2. Database Casts

    • Update for nullable fields:
      class JalaliDateAttribute extends Attribute {
          public function get($model) {
              return $model->{$this->name}?->jalali();
          }
      }
      
  3. Testing

    • Mock nullable inputs:
      $this->assertNull(Jalalianizator::jalali(null));
      Carbon::setTestNow(Jalalianizator::gregorian('1400/01/01'));
      
  4. Laravel Scout

    • Unchanged: Index Gregorian dates, display Jalali:
      $model->searchableAs('event_date')->attributesToSearch(['date']);
      // In results:
      $event->date?->jalali();
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle