pulseline / jalali-events
A Laravel package for Iranian Jalali calendar events, official holidays, date ranges, and automatic calendar synchronization.
Package info
github.com/Pulselineir/jalali-events
Language:HTML
pkg:composer/pulseline/jalali-events
Requires
- php: ^8.3
- hekmatinasser/verta: ^9.0
- illuminate/console: ^13.0
- illuminate/database: ^13.0
- illuminate/http: ^13.0
- illuminate/support: ^13.0
- symfony/dom-crawler: ^7.3 || ^8.0
Requires (Dev)
- orchestra/testbench: ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Jalali Events
Iranian Jalali Calendar Events & Official Holidays for Laravel
A Laravel package for fetching, storing, querying, and automatically synchronizing Iranian Jalali calendar events and official holidays.
Features
Jalali Events provides a simple API for working with the Iranian calendar in Laravel applications.
- Fetch complete Jalali calendar years
- Store Iranian events and occasions
- Detect official holidays
- Detect weekends separately from official holidays
- Query individual Jalali dates
- Retrieve all events for a date
- Query arbitrary date ranges
- Count holidays within a range
- Synchronize calendar data from
time.ir - Automatic scheduled synchronization
- Database storage
- JSON storage
- PostgreSQL compatible
- MySQL and MariaDB compatible
- SQLite compatible
- Laravel auto-discovery
Installation
Install the package using Composer:
composer require pulseline/jalali-events
Laravel will automatically discover the package service provider.
Run the package migrations:
php artisan migrate
Then synchronize the current Jalali year:
php artisan jalali-events:sync
Or synchronize a specific year:
php artisan jalali-events:sync 1405
Quick Start
The package provides the JalaliEvents facade.
use JalaliEvents;
Get information about a Jalali date:
$day = JalaliEvents::date('1405/04/03');
Example result:
[
'jalali_year' => 1405,
'jalali_month' => 4,
'jalali_day' => 3,
'jalali_date' => '1405/04/03',
'gregorian_date' => '2026-06-24',
'weekday' => 3,
'is_holiday' => true,
'is_weekend' => false,
'source' => 'time.ir',
'events' => [
[
'title' => 'تاسوعای حسینی',
'category' => 'hijri',
'is_holiday' => true,
],
],
];
Check Whether a Date Is a Holiday
$isHoliday = JalaliEvents::isHoliday( '1405/04/03' );
Returns:
true
Get Events for a Date
$events = JalaliEvents::events( '1405/04/03' );
Example:
[
[
'title' => 'تاسوعای حسینی',
'category' => 'hijri',
'is_holiday' => true,
],
]
A single date can contain multiple events.
Query a Date Range
$days = JalaliEvents::between( '1405/04/01', '1405/04/10' );
This returns all calendar days between the two supplied Jalali dates.
Holidays in a Date Range
$holidays = JalaliEvents::holidaysBetween( '1405/04/01', '1405/04/31' );
Count Holidays
$count = JalaliEvents::holidayCount( '1405/04/01', '1405/04/31' );
Calendar Synchronization
Synchronize a specific Jalali year:
php artisan jalali-events:sync 1405
Synchronize the current Jalali year:
php artisan jalali-events:sync
Synchronization downloads calendar data from the configured upstream source and stores the normalized result locally.
Application queries do not request data from time.ir.
The normal flow is:
time.ir
|
v
Calendar Source
|
v
Parser
|
v
Normalizer
|
v
Calendar Updater
|
v
Database / JSON
|
v
Application API
This means the application queries its own local storage instead of calling the upstream website for every request.
Storage
Jalali Events supports two storage drivers:
- Database
- JSON
Database Storage
Database storage is the default:
JALALI_EVENTS_STORAGE=database
The package creates two tables:
jalali_calendar_days
jalali_events
The jalali_calendar_days table stores one record for each calendar day.
The jalali_events table supports multiple events for each day.
PostgreSQL, MySQL, MariaDB and SQLite
By default, Jalali Events uses the Laravel application's default database connection.
For example, if the Laravel application uses PostgreSQL:
DB_CONNECTION=pgsql DB_HOST=127.0.0.1 DB_PORT=5432 DB_DATABASE=my_application DB_USERNAME=postgres DB_PASSWORD=secret
Jalali Events will store its tables in the same PostgreSQL database.
No additional configuration is required.
The same approach applies when the main Laravel project uses MySQL, MariaDB, or SQLite.
Dedicated Database Connection
Calendar data can optionally be stored using a separate Laravel database connection.
JALALI_EVENTS_DB_CONNECTION=jalali
Then define the jalali connection inside:
config/database.php
Example:
'connections' => [ 'jalali' => [ 'driver' => 'pgsql', 'host' => env('JALALI_DB_HOST', '127.0.0.1'), 'port' => env('JALALI_DB_PORT', '5432'), 'database' => env('JALALI_DB_DATABASE'), 'username' => env('JALALI_DB_USERNAME'), 'password' => env('JALALI_DB_PASSWORD'), 'charset' => 'utf8', 'prefix' => '', 'schema' => 'public', 'sslmode' => 'prefer', ], ],
JSON Storage
To use JSON instead of a database:
JALALI_EVENTS_STORAGE=json
The default JSON file is stored at:
storage/app/jalali-events/calendar.json
Publishing Configuration
Publish the package configuration:
php artisan vendor:publish --tag=jalali-events-config
This creates:
config/jalali-events.php
Configuration
Available environment variables:
JALALI_EVENTS_STORAGE=database JALALI_EVENTS_DB_CONNECTION= JALALI_EVENTS_AUTO_UPDATE=true JALALI_EVENTS_UPDATE_FREQUENCY=monthly JALALI_EVENTS_HTTP_TIMEOUT=15 JALALI_EVENTS_HTTP_RETRY=3 JALALI_EVENTS_HTTP_RETRY_SLEEP=1000 JALALI_EVENTS_VERIFY_SSL=true JALALI_EVENTS_USER_AGENT="JalaliEvents Laravel Package"
Automatic Updates
Automatic synchronization is enabled by default:
JALALI_EVENTS_AUTO_UPDATE=true
Available frequencies:
JALALI_EVENTS_UPDATE_FREQUENCY=daily
JALALI_EVENTS_UPDATE_FREQUENCY=weekly
JALALI_EVENTS_UPDATE_FREQUENCY=monthly
The default is:
monthly
Jalali Events schedules the following command automatically:
php artisan jalali-events:sync
The Laravel scheduler must be configured on the host application.
A typical cron entry is:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
SSL Verification
SSL verification is enabled by default:
JALALI_EVENTS_VERIFY_SSL=true
Disabling SSL verification is not recommended in production.
If the development environment uses an internal Certificate Authority or SSL inspection proxy, configure PHP and cURL with the appropriate CA certificate instead of disabling SSL verification.
Calendar Source
The default upstream calendar source is:
time.ir
The source layer is separated from the rest of the package architecture so alternative calendar providers can be implemented in future versions without changing the public API.
The package dynamically resolves the Next.js Server Action used by the upstream calendar service instead of relying on a permanently hard-coded action identifier.
Since time.ir is an external service, changes to its internal implementation may require a package update.
Architecture
CalendarSourceInterface
|
v
TimeIrSource
|
v
TimeIrParser
|
v
CalendarUpdater
|
v
CalendarRepositoryInterface
/ \
/ \
Database JSON
Repository Repository
\ /
\ /
v
CalendarService
|
v
JalaliEvents
Testing
Install development dependencies:
composer install
Run the complete test suite:
composer test
or:
vendor/bin/phpunit
Validate Composer metadata:
composer validate
Requirements
- PHP 8.3+
- Laravel / Illuminate 13.x
- Composer
- PostgreSQL, MySQL, MariaDB, or SQLite
- Internet access during calendar synchronization
The application does not require internet access when reading previously synchronized calendar data.
Contributing
Contributions are welcome.
- Fork the repository.
- Create a feature branch.
- Make the required changes.
- Add or update tests where appropriate.
- Run the complete test suite.
- Submit a pull request.
Repository:
https://github.com/Pulselineir/jalali-events
Issues
Bug reports and feature requests can be submitted through GitHub Issues:
https://github.com/Pulselineir/jalali-events/issues
Security
For security-related issues, please avoid publishing sensitive information in a public issue.
Contact:
pulseline.ir@gmail.com
Author
Farzin Bidokhti
GitHub: @farzinbidokhti
Jalali Events is developed and maintained under Pulseline:
License
Jalali Events is open-source software licensed under the MIT License.