imrandevbd / tarikh
A modern, immutable, Laravel-native date/time toolkit with built-in South Asian calendar, holiday, and locale support.
Requires
- php: ^8.3
- ext-intl: *
Requires (Dev)
- laravel/pint: ^1.13
- pestphp/pest: ^3.0
- phpstan/phpstan: ^1.10
Suggests
- illuminate/database: Required for Eloquent casting (^10.0|^11.0).
- illuminate/support: Required to use the Laravel integration (^10.0|^11.0).
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-16 22:14:10 UTC
README
Tarikh (تاریخ / তারিখ) is an ultra-fast, modern, and immutable DateTime toolkit engineered from the ground up for PHP 8.3+ and Laravel. Designed as an elegant, lightweight alternative to legacy date libraries, Tarikh guarantees zero unwanted side-effects through strict immutability, microsecond precision, macroable extensibility, and seamless developer ergonomics.
⚡ Highlights & Key Features
- 🔒 100% Immutable by Design: Every modification returns a pristine new instance. Say goodbye to accidental mutation bugs in loops and queries.
- 🚀 Built for Modern PHP 8.3+: Type-safe backed enums (
Unit,Month,Weekday), strict types, and zero legacy bloat. - 🧪 Time Travel & Testing Mock: Built-in
setTestNow()for deterministic testing across suites. - 🎯 Fluent Sugar Modifiers: Intuitive arithmetic (
addDays(),subMonths(),addHours(), etc.). - 📐 Boundary Precision: Precise
startOf()andendOf()boundaries down to the microsecond (Second,Minute,Hour,Day,Week,Month,Quarter,Year). - ⚖️ Rich Comparisons:
isBefore(),isAfter(),isBetween(),isWeekend(),isLeapYear(), and more. - 📊 Detailed Diff Engine: High-precision difference metrics (
diffInSeconds,diffInMinutes,diffInHours,diffInDays,diffInWeeks,diffInMonths,diffInYears). - 🔌 Macroable & Extensible: Add custom domain logic or regional calendar rules at runtime via
Tarikh::macro()andTarikh::mixin(). - 📦 First-Class Laravel Integration: Auto-discovered Service Provider and Facade ready out of the box.
📥 Installation
Install via Composer:
composer require imrandevbd/tarikh
Requirements: PHP 8.3 or higher with the ext-intl extension.
🚀 Quick Start
use Tarikh\Tarikh; use Tarikh\Enums\Unit; // Create instances $now = Tarikh::now(); $today = Tarikh::today('Asia/Dhaka'); $event = Tarikh::parse('2025-12-31 23:59:59', 'UTC'); // Immutable arithmetic $nextWeek = $now->addWeeks(1); $prevQuarter = $now->sub(1, Unit::Quarter); // Boundaries $monthStart = $now->startOf(Unit::Month); // YYYY-MM-01 00:00:00 $monthEnd = $now->endOf(Unit::Month); // YYYY-MM-31 23:59:59.999999 // Human-friendly formats echo $now->toDateString(); // "2025-05-15" echo $now->toDateTimeString(); // "2025-05-15 14:30:00" echo $now->toIso8601String(); // "2025-05-15T14:30:00+00:00"
📖 Complete Feature Guide
1. Creation & Parsing
use Tarikh\Tarikh; // Current timestamp $now = Tarikh::now(); $nowDhaka = Tarikh::now('Asia/Dhaka'); // Start of today, tomorrow, yesterday $today = Tarikh::today(); $tomorrow = Tarikh::tomorrow(); $yesterday = Tarikh::yesterday(); // Parse strings or DateTimeInterface $date = Tarikh::parse('2025-06-15 18:30:00', 'America/New_York'); // Explicit constructor $created = Tarikh::create(year: 2025, month: 12, day: 25, hour: 10, minute: 0, second: 0, tz: 'UTC'); // From UNIX timestamp $fromEpoch = Tarikh::fromTimestamp(1735689600);
2. Time Travel & Testing (setTestNow)
Freeze or shift time during unit tests effortlessly:
use Tarikh\Tarikh; // Freeze time for tests Tarikh::setTestNow(Tarikh::parse('2024-01-01 12:00:00')); echo Tarikh::now()->toDateTimeString(); // "2024-01-01 12:00:00" echo Tarikh::today()->toDateTimeString(); // "2024-01-01 00:00:00" // Reset back to system time Tarikh::setTestNow(null);
3. Date Arithmetic & Modifiers
All operations return a new instance without mutating the original object:
use Tarikh\Tarikh; use Tarikh\Enums\Unit; $tarikh = Tarikh::parse('2025-01-15 12:00:00'); // Enums-based manipulation $modified = $tarikh ->add(2, Unit::Day) ->sub(1, Unit::Month) ->add(3, Unit::Hour); // Convenient fluent modifiers $tarikh->addDays(5); $tarikh->subDays(2); $tarikh->addWeeks(3); $tarikh->subWeeks(1); $tarikh->addMonths(6); $tarikh->subMonths(2); $tarikh->addYears(1); $tarikh->subYears(5); $tarikh->addHours(4); $tarikh->subHours(2); $tarikh->addMinutes(30); $tarikh->subMinutes(15); $tarikh->addSeconds(45); $tarikh->subSeconds(10);
4. Boundary Calculation (startOf & endOf)
Accurately calculate periods down to the microsecond:
use Tarikh\Tarikh; use Tarikh\Enums\Unit; $date = Tarikh::parse('2025-05-15 14:30:45'); // Start of periods $startOfDay = $date->startOf(Unit::Day); // 2025-05-15 00:00:00 $startOfWeek = $date->startOf(Unit::Week); // Monday of the week 00:00:00 $startOfMonth = $date->startOf(Unit::Month); // 2025-05-01 00:00:00 $startOfQuarter = $date->startOf(Unit::Quarter); // 2025-04-01 00:00:00 $startOfYear = $date->startOf(Unit::Year); // 2025-01-01 00:00:00 // End of periods (with microsecond precision: 23:59:59.999999) $endOfDay = $date->endOf(Unit::Day); $endOfWeek = $date->endOf(Unit::Week); // Sunday 23:59:59.999999 $endOfMonth = $date->endOf(Unit::Month); $endOfYear = $date->endOf(Unit::Year);
5. Comparisons & State Checks
use Tarikh\Tarikh; $t1 = Tarikh::parse('2025-01-01'); $t2 = Tarikh::parse('2025-01-15'); $t3 = Tarikh::parse('2025-02-01'); // Relative comparisons $t1->isBefore($t2); // true $t2->isAfter($t1); // true $t1->equalTo($t1); // true $t2->isBetween($t1, $t3); // true // Same unit checks $t1->isSameDay($t2); // false $t1->isSameMonth($t2); // true $t1->isSameYear($t3); // true // State predicates $t1->isWeekend(); // true/false $t1->isWeekday(); // true/false $t1->isToday(); // true/false $t1->isFuture(); // true/false $t1->isPast(); // true/false $t1->isLeapYear(); // true/false
6. Differences & Intervals
Calculate precise differences between two dates:
use Tarikh\Tarikh; $start = Tarikh::parse('2025-01-01 00:00:00'); $end = Tarikh::parse('2025-01-05 12:00:00'); $start->diffInSeconds($end); // 388800 $start->diffInMinutes($end); // 6480.0 $start->diffInHours($end); // 108.0 $start->diffInDays($end); // 4.5 $start->diffInWeeks($end); // ~0.64 $start->diffInMonths($end); // Float month difference $start->diffInYears($end); // Float year difference
7. Formatting & JSON Serialization
$tarikh = Tarikh::parse('2025-07-20 18:30:45', 'Asia/Tokyo'); // Standard outputs $tarikh->toDateString(); // "2025-07-20" $tarikh->toTimeString(); // "18:30:45" $tarikh->toDateTimeString(); // "2025-07-20 18:30:45" $tarikh->toIso8601String(); // "2025-07-20T18:30:45+09:00" $tarikh->toRfc3339String(); // "2025-07-20T18:30:45+09:00" $tarikh->format('l, F j, Y'); // "Sunday, July 20, 2025" // Debug inspection $tarikh->explain(); // [ // 'datetime' => '2025-07-20 18:30:45', // 'timezone' => 'Asia/Tokyo', // 'timestamp' => 1753003845, // ] // Automatic JSON serialization (implements JsonSerializable) json_encode(['event_at' => $tarikh]);
8. Macroable & Custom Extensibility
Extend Tarikh at runtime using the Macroable trait:
use Tarikh\Tarikh; // Define a macro Tarikh::macro('isIndependenceDay', function () { return $this->format('m-d') === '03-26'; }); $day = Tarikh::parse('2025-03-26'); echo $day->isIndependenceDay(); // true
9. Laravel Integration
Tarikh automatically hooks into Laravel. If you prefer using the Facade:
use Tarikh\Laravel\Facades\Tarikh; $now = Tarikh::now(); $deadline = Tarikh::parse($request->input('due_date'))->endOfDay();
🧪 Testing
Run test suite via Pest:
composer test
Or run static analysis and code styling:
vendor/bin/phpstan analyse vendor/bin/pint --test
🤝 Let's Connect & Collaborate
I am open to Senior Remote Full-Stack Roles, AI Platform Architecture Contracts, and Enterprise Technical Advisory.
- Timezone: UTC+6 (Dhaka / Rangpur, Bangladesh) — Flexible overlap with US, UK, and European business hours.
- Delivery Mode: Async-ready, Slack, Discord, Jira, GitHub, and production-first accountability.
| Channel | Address / Handle | Quick Action |
|---|---|---|
| 🌐 Primary Portfolio | imrandev.bd | Visit Site ↗ |
| 📦 Packagist Packages | packagist.org/packages/imrandevbd/ | View Packages ↗ |
| 💼 LinkedIn Profile | linkedin.com/in/imranbru99 | Connect ↗ |
| 🐙 GitHub Profile | github.com/imranbru99 | Follow ↗ |
| 💬 WhatsApp Direct | +880 1576-918420 | Chat Now ↗ |
| 📧 Direct Email | me@imrandev.bd | Send Email ↗ |
| 🐦 X (Twitter) | @imrandev_bd | Follow ↗ |
| 📺 YouTube Tech | @ImranDevBD | Subscribe ↗ |
📄 License
The MIT License (MIT). Please see License File for more information.