From 9e4730b19314fe39848a89ded1d1475d1eb7f13e Mon Sep 17 00:00:00 2001 From: Morteza Parvini Date: Sun, 7 Aug 2022 12:52:02 +0430 Subject: [PATCH 1/4] chore: update .gitignore --- .gitignore | 3 ++- tests/CalendarUtilsTest.php | 33 +++++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 38cdbd7..28c68e4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ composer.phar composer.lock .DS_Store -.idea \ No newline at end of file +.idea +.phpunit.* \ No newline at end of file diff --git a/tests/CalendarUtilsTest.php b/tests/CalendarUtilsTest.php index ff1fae5..5ed4bbe 100644 --- a/tests/CalendarUtilsTest.php +++ b/tests/CalendarUtilsTest.php @@ -38,14 +38,29 @@ public function testIsLeapJalaliYear() public function testStrftime() { - $this->assertTrue(CalendarUtils::strftime('Y-m-d', strtotime('2016-05-8')) === '1395-02-19'); - $this->assertTrue(CalendarUtils::convertNumbers(CalendarUtils::strftime('Y-m-d', - strtotime('2016-05-8'))) === '۱۳۹۵-۰۲-۱۹'); - - $dateString = CalendarUtils::convertNumbers('۱۳۹۵-۰۲-۱۹', true); // 1395-02-19 - $this->assertTrue(CalendarUtils::createCarbonFromFormat('Y-m-d', - $dateString)->format('Y-m-d') === '2016-05-08'); - $this->assertFalse(CalendarUtils::strftime('Y-m-d', strtotime('2016-05-8')) === '۱۳۹۵-۰۲-۱۹'); + $table = [ + [ + '2016-05-08', + 'Y-m-d', + '1395-02-19' + ], + [ + '2022-03-24', + 'y-m-d', + '01-01-04' + ], + [ + '2023-03-24', + 'y-m-D', + '02-01-ج' + ], + ]; + + foreach ($table as $row) { + list($dateTimeString, $format, $expected) = $row; + $timestamp = strtotime($dateTimeString); + $this->assertEquals($expected, CalendarUtils::strftime($format, $timestamp)); + } } public function test_parseFromPersian() @@ -86,7 +101,6 @@ public function testCreateCarbonFormFormat() $jalaiDateTimeFormatted = Jalalian::fromDateTime($carbon->toDateTimeString())->format('Y-m-d H:i:s'); $this->assertFalse($jalaiDateFormatted === '1394-11-25 15:00:00'); $this->assertTrue($jalaiDateTimeFormatted === '1394-11-25 15:00:00'); - } public function testTimezone() @@ -104,7 +118,6 @@ public function testTimezone() $tzOffset = $this->getTimeZoneOffset('Asia/Tehran', 'UTC'); $this->assertTrue((((($utcHour * 60) + $utcMin) * 60) - ((($tehranHour * 60) + $tehranMin) * 60)) === $tzOffset); - } From a0e792582b0744991a77b896362f4a097d7d6c88 Mon Sep 17 00:00:00 2001 From: Morteza Parvini Date: Sun, 7 Aug 2022 12:54:37 +0430 Subject: [PATCH 2/4] fix(phpunit): remove syntaxCheck attribute from phpunit configuration --- phpunit.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 4eceac6..d2d2c99 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -7,8 +7,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false" - syntaxCheck="false"> + stopOnFailure="true"> ./tests/ From 1b0d8f0e25dca6da6c37b6f37c2b1f816f145f1b Mon Sep 17 00:00:00 2001 From: Morteza Parvini Date: Sun, 7 Aug 2022 13:17:02 +0430 Subject: [PATCH 3/4] test: add test case to proof the package support date conversion after 1416 --- tests/CalendarUtilsTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/CalendarUtilsTest.php b/tests/CalendarUtilsTest.php index 5ed4bbe..24fb468 100644 --- a/tests/CalendarUtilsTest.php +++ b/tests/CalendarUtilsTest.php @@ -101,6 +101,10 @@ public function testCreateCarbonFormFormat() $jalaiDateTimeFormatted = Jalalian::fromDateTime($carbon->toDateTimeString())->format('Y-m-d H:i:s'); $this->assertFalse($jalaiDateFormatted === '1394-11-25 15:00:00'); $this->assertTrue($jalaiDateTimeFormatted === '1394-11-25 15:00:00'); + + // Test support years after 1416 + $carbon = CalendarUtils::createCarbonFromFormat('Y/m/d', '1417/10/11'); + $this->assertEquals('2039-01-01', $carbon->format('Y-m-d')); } public function testTimezone() From 6b96a605ffc4074de00f0536a20369b2a975ed89 Mon Sep 17 00:00:00 2001 From: Morteza Parvini Date: Sun, 7 Aug 2022 13:45:09 +0430 Subject: [PATCH 4/4] feat: now months name could be configured globally Iranian months name used as default. To switch between iranian and aghan month names you can use `CalendarUtils::useAfghanMonthsName()` and `CalendarUtils::useIranianMonthsName()` --- src/CalendarUtils.php | 126 ++++++++++++++++-------------------- tests/CalendarUtilsTest.php | 31 +++++++++ 2 files changed, 86 insertions(+), 71 deletions(-) diff --git a/src/CalendarUtils.php b/src/CalendarUtils.php index a0914b7..aa288a8 100644 --- a/src/CalendarUtils.php +++ b/src/CalendarUtils.php @@ -1,4 +1,5 @@ setDate($year, $month, $day); - - + + return $georgianDate; } @@ -75,8 +102,8 @@ public static function toGregorianDate($jy, $jm, $jd) public static function isValidateJalaliDate($jy, $jm, $jd) { return $jy >= -61 && $jy <= 3177 - && $jm >= 1 && $jm <= 12 - && $jd >= 1 && $jd <= self::jalaliMonthLength($jy, $jm); + && $jm >= 1 && $jm <= 12 + && $jd >= 1 && $jd <= self::jalaliMonthLength($jy, $jm); } /** @@ -141,8 +168,8 @@ public static function jalaliMonthLength($jy, $jm) */ public static function jalaliCal($jy) { - $breaks = [-61, 9, 38, 199, 426, 686, 756, 818, 1111, 1181, 1210 - , 1635, 2060, 2097, 2192, 2262, 2324, 2394, 2456, 3178 + $breaks = [ + -61, 9, 38, 199, 426, 686, 756, 818, 1111, 1181, 1210, 1635, 2060, 2097, 2192, 2262, 2324, 2394, 2456, 3178 ]; $breaksCount = count($breaks); @@ -203,9 +230,9 @@ public static function jalaliCal($jy) * @param $a * @param $b */ - public static function div($a, $b):int + public static function div($a, $b): int { - return intdiv($a ,$b); + return intdiv($a, $b); } /** @@ -213,9 +240,9 @@ public static function div($a, $b):int * @param $b * @return mixed */ - public static function mod($a, $b):int + public static function mod($a, $b): int { - return $a - intdiv($a , $b) * $b; + return $a - intdiv($a, $b) * $b; } /** @@ -249,12 +276,10 @@ public static function d2g($jdn) */ public static function g2d($gy, $gm, $gd) { - return ( - self::div(($gy + self::div($gm - 8, 6) + 100100) * 1461, 4) + return (self::div(($gy + self::div($gm - 8, 6) + 100100) * 1461, 4) + self::div(153 * self::mod($gm + 9, 12) + 2, 5) + $gd - 34840408 ) - self::div(self::div($gy + 100100 + self::div($gm - 8, 6), 100) * 3, 4) + 752; - } /** @@ -374,7 +399,6 @@ public static function date($format, $stamp = false, $timezone = null) $values = array(); foreach ($keys as $k => $key) { - $v = ''; switch ($key) { //Day @@ -407,19 +431,19 @@ public static function date($format, $stamp = false, $timezone = null) } self::$temp['z'] = $v; break; - //Week + //Week case 'W': $v = is_int(self::$temp['z'] / 7) ? (self::$temp['z'] / 7) : intval(self::$temp['z'] / 7 + 1); break; - //Month + //Month case 'F': - $v = self::getMonthNames($jMonth); + $v = self::getMonthName($jMonth); break; case 'm': $v = sprintf("%02d", $jMonth); break; case 'M': - $v = self::getMonthNames($jMonth, true); + $v = self::getMonthName($jMonth, true); break; case 'n': $v = $jMonth; @@ -427,7 +451,7 @@ public static function date($format, $stamp = false, $timezone = null) case 't': $v = ($jMonth == 12) ? (self::isLeapJalaliYear($jYear) ? 30 : 29) : ($jMonth > 6 ? 30 : 31); break; - //Year + //Year case 'L': $tmpObj = static::createDateTime(time() - 31536000, $timezone); $v = $tmpObj->format('L'); @@ -442,34 +466,34 @@ public static function date($format, $stamp = false, $timezone = null) $v = '0' . $v; } break; - //Time + //Time case 'a': $v = ($dateTime->format('a') == 'am') ? 'ق.ظ' : 'ب.ظ'; break; case 'A': $v = ($dateTime->format('A') == 'AM') ? 'قبل از ظهر' : 'بعد از ظهر'; break; - //Full Dates + //Full Dates case 'c': $v = $jYear . '-' . sprintf("%02d", $jMonth) . '-' . sprintf("%02d", $jDay) . 'T'; $v .= $dateTime->format('H') . ':' . $dateTime->format('i') . ':' . $dateTime->format('s') . $dateTime->format('P'); break; case 'r': - $v = self::getDayNames($dateTime->format('D'), true) . ', ' . sprintf("%02d", - $jDay) . ' ' . self::getMonthNames($jMonth, true); + $v = self::getDayNames($dateTime->format('D'), true) . ', ' . sprintf( + "%02d", + $jDay + ) . ' ' . self::getMonthName($jMonth, true); $v .= ' ' . $jYear . ' ' . $dateTime->format('H') . ':' . $dateTime->format('i') . ':' . $dateTime->format('s') . ' ' . $dateTime->format('P'); break; - //Timezone + //Timezone case 'e': $v = $dateTime->format('e'); break; case 'T': $v = $dateTime->format('T'); break; - } $values[$k] = $v; - } //End Changed Keys @@ -627,49 +651,11 @@ private static function getDayNames($day, $shorten = false, $len = 1, $numeric = return ($numeric) ? $n : (($shorten) ? mb_substr($ret, 0, $len, 'UTF-8') : $ret); } - private static function getMonthNames($month, $shorten = false, $len = 3) + private static function getMonthName($month, $shorten = false, $len = 3) { - $ret = ''; - switch ($month) { - case '1': - $ret = 'فروردین'; - break; - case '2': - $ret = 'اردیبهشت'; - break; - case '3': - $ret = 'خرداد'; - break; - case '4': - $ret = 'تیر'; - break; - case '5': - $ret = 'مرداد'; - break; - case '6': - $ret = 'شهریور'; - break; - case '7': - $ret = 'مهر'; - break; - case '8': - $ret = 'آبان'; - break; - case '9': - $ret = 'آذر'; - break; - case '10': - $ret = 'دی'; - break; - case '11': - $ret = 'بهمن'; - break; - case '12': - $ret = 'اسفند'; - break; - } - - return ($shorten) ? mb_substr($ret, 0, $len, 'UTF-8') : $ret; + $monthIndex = ((int)$month) -1 ; + $monthName = static::$monthNames[$monthIndex]; + return ($shorten) ? mb_substr($monthName, 0, $len, 'UTF-8') : $monthName; } private static function filterArray($needle, $haystack, $always = array()) @@ -678,7 +664,6 @@ private static function filterArray($needle, $haystack, $always = array()) if (!in_array($v, $needle) && !in_array($v, $always)) { unset($haystack[$k]); } - } @@ -797,7 +782,7 @@ public static function createDatetimeFromFormat($format, $str, $timezone = null) public static function createCarbonFromFormat($format, $str, $timezone = null) { $dateTime = self::createDatetimeFromFormat($format, $str, $timezone); - + return Carbon::createFromTimestamp($dateTime->getTimestamp(), $dateTime->getTimezone()); } @@ -868,6 +853,5 @@ public static function createTimeZone($timezone = null) throw new \InvalidArgumentException('timezone is not valid'); - } } diff --git a/tests/CalendarUtilsTest.php b/tests/CalendarUtilsTest.php index 24fb468..364b8b3 100644 --- a/tests/CalendarUtilsTest.php +++ b/tests/CalendarUtilsTest.php @@ -63,6 +63,37 @@ public function testStrftime() } } + public function testFormatMonthName() + { + $months = range(1, 12); + + // Should returns iranian months name as default + foreach ($months as $month) { + $date = sprintf('1401/%d/10', $month); + $actual = Jalalian::fromFormat('Y/n/d', $date)->format('F'); + $expected = CalendarUtils::IRANIAN_MONTHS_NAME[$month - 1]; + $this->assertEquals($expected, $actual); + } + + // Should returns afghan months name when set + CalendarUtils::useAfghanMonthsName(); + foreach ($months as $month) { + $date = sprintf('1401/%d/10', $month); + $actual = Jalalian::fromFormat('Y/n/d', $date)->format('F'); + $expected = CalendarUtils::AFGHAN_MONTHS_NAME[$month - 1]; + $this->assertEquals($expected, $actual); + } + + // Should returns afghan months name when set + CalendarUtils::useIranianMonthsName(); + foreach ($months as $month) { + $date = sprintf('1401/%d/10', $month); + $actual = Jalalian::fromFormat('Y/n/d', $date)->format('F'); + $expected = CalendarUtils::IRANIAN_MONTHS_NAME[$month - 1]; + $this->assertEquals($expected, $actual); + } + } + public function test_parseFromPersian() { $jalaliDate = '1393/03/27';