service = new JalaliDateService(); } /** نوروز لنگرِ همه‌چیز است: ۱ فروردین ۱۴۰۵ = ۲۱ مارس ۲۰۲۶. */ public function testNowruzAnchor(): void { self::assertSame([2026, 3, 21], $this->service->jalaliToGregorian(1405, 1, 1)); self::assertSame([1405, 1, 1], $this->service->gregorianToJalali(2026, 3, 21)); } public function testRoundTripAcrossTheYear(): void { foreach ([[1405, 1, 1], [1405, 5, 8], [1405, 6, 31], [1405, 7, 1], [1405, 12, 29]] as [$jy, $jm, $jd]) { [$gy, $gm, $gd] = $this->service->jalaliToGregorian($jy, $jm, $jd); self::assertSame( [$jy, $jm, $jd], $this->service->gregorianToJalali($gy, $gm, $gd), sprintf('رفت‌وبرگشت %d/%d/%d', $jy, $jm, $jd), ); } } /** مهر اول نیم‌سال دوم است و ماه‌هایش ۳۰ روزه — مرز ۶/۳۱ به ۷/۱. */ public function testSixthMonthHasThirtyOneDaysAndSeventhStartsNextDay(): void { [$gy, $gm, $gd] = $this->service->jalaliToGregorian(1405, 6, 31); $end = (new \DateTimeImmutable(sprintf('%04d-%02d-%02d', $gy, $gm, $gd)))->modify('+1 day'); self::assertSame( [1405, 7, 1], $this->service->gregorianToJalali( (int) $end->format('Y'), (int) $end->format('n'), (int) $end->format('j'), ), ); } public function testJalaliYearOfAKnownTimestamp(): void { $timestamp = (new \DateTimeImmutable('2026-07-30 12:00:00', new \DateTimeZone('Asia/Tehran')))->getTimestamp(); self::assertSame(1405, $this->service->jalaliYear($timestamp)); self::assertSame(5, $this->service->jalaliMonth($timestamp)); } /** بازهٔ سال باید نوروز تا آخر اسفند باشد، نه چیزی در قرن سی‌ویکم. */ public function testYearRangeStartsAtNowruz(): void { [$start, $end] = $this->service->jalaliYearRange(1405); self::assertSame('2026-03-21', date('Y-m-d', $start)); self::assertGreaterThan($start, $end); self::assertSame(1405, $this->service->jalaliYear($start)); } }