Last active
January 11, 2024 09:27
-
-
Save jfcherng/4eb9c81c95b42a1b9f188a7f70f4e420 to your computer and use it in GitHub Desktop.
Revisions
-
jfcherng revised this gist
Jan 10, 2024 . 1 changed file with 6 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -103,9 +103,6 @@ public function convertSolarToLunar(int $year, int $month, int $date): array public function convertSolarMonthToLunar(int $year, int $month): array { $yearData = static::LUNAR_INFO[$year - static::MIN_YEAR]; $dd = $this->getSolarMonthDays($year, $month); if ($this->isLeapYear($year) && $month === 2) { @@ -247,7 +244,6 @@ public function getLunarMonths(int $year): array */ public function getLunarYearDays(int $year): int { $monthArray = $this->getLunarYearMonths($year); $len = count($monthArray); @@ -426,6 +422,9 @@ public function getCapitalNum(int $num, bool $isMonth = false): string } } function demo() { $lunar = new Lunar(); $month = $lunar->convertSolarToLunar(2018, 1, 2); print_r($month); } // demo(); -
jfcherng revised this gist
Jun 18, 2018 . 1 changed file with 9 additions and 9 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -89,8 +89,8 @@ class Lunar public function convertSolarToLunar(int $year, int $month, int $date): array { //debugger; $yearData = static::LUNAR_INFO[$year - static::MIN_YEAR]; if ($year === static::MIN_YEAR && $month <= 2 && $date <= 9) { return [1891, '正月', '初一', '辛卯', 1, 1, '兔']; } @@ -102,8 +102,8 @@ public function convertSolarToLunar(int $year, int $month, int $date): array public function convertSolarMonthToLunar(int $year, int $month): array { $yearData = static::LUNAR_INFO[$year - static::MIN_YEAR]; if ($year === static::MIN_YEAR && $month <= 2 && $date <= 9) { return [1891, '正月', '初一', '辛卯', 1, 1, '兔']; } @@ -136,7 +136,7 @@ public function convertSolarMonthToLunar(int $year, int $month): array */ public function convertLunarToSolar(int $year, int $month, int $date): array { $yearData = static::LUNAR_INFO[$year - static::MIN_YEAR]; $between = $this->getDaysBetweenLunar($year, $month, $date); $res = mktime(0, 0, 0, $yearData[1], $yearData[2], $year); @@ -218,7 +218,7 @@ public function getLunarMonthDays(int $year, int $month): int */ public function getLunarMonths(int $year): array { $yearData = static::LUNAR_INFO[$year - static::MIN_YEAR]; $leapMonth = $yearData[0]; $bit = decbin($yearData[3]); @@ -247,7 +247,7 @@ public function getLunarMonths(int $year): array */ public function getLunarYearDays(int $year): int { $yearData = static::LUNAR_INFO[$year - static::MIN_YEAR]; $monthArray = $this->getLunarYearMonths($year); $len = count($monthArray); @@ -267,7 +267,7 @@ public function getLunarYearMonths(int $year): array $monthData = $this->getLunarMonths($year); $res = []; $temp = 0; $yearData = static::LUNAR_INFO[$year - static::MIN_YEAR]; $len = ($yearData[0] === 0 ? 12 : 13); for ($i = 0; $i < $len; ++$i) { @@ -290,7 +290,7 @@ public function getLunarYearMonths(int $year): array */ public function getLeapMonth(int $year): int { return static::LUNAR_INFO[$year - static::MIN_YEAR][0]; } /** -
jfcherng revised this gist
Jun 18, 2018 . 1 changed file with 111 additions and 88 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -43,21 +43,54 @@ class Lunar [0, 2, 5, 19168], [4, 1, 25, 42216], [0, 2, 12, 42192], [0, 2, 1, 53584], [2, 1, 21, 55592], [0, 2, 9, 54560], ]; const SKY = [ '庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己', ]; const EARTH = [ '申', '酉', '戌', '亥', '子', '丑', '寅', '卯', '辰', '巳', '午', '未', ]; const ZODIAC = [ '猴', '雞', '狗', '豬', '鼠', '牛', '虎', '兔', '龍', '蛇', '馬', '羊', ]; const DATE_HASH = [ '', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十', ]; const MONTH_HASH = [ '', '正月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '冬月', '臘月', ]; const MONTH_DAYS = [ 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, ]; /** * 將陽曆轉換為陰曆. * * @param int $year 公曆-年 * @param int $month 公曆-月 * @param int $date 公曆-日 * * @return array */ public function convertSolarToLunar(int $year, int $month, int $date): array { //debugger; $yearData = self::LUNAR_INFO[$year - self::MIN_YEAR]; if ($year === self::MIN_YEAR && $month <= 2 && $date <= 9) { return [1891, '正月', '初一', '辛卯', 1, 1, '兔']; } @@ -67,17 +100,18 @@ public function convertSolarToLunar(string $year, string $month, string $date): ); } public function convertSolarMonthToLunar(int $year, int $month): array { $yearData = self::LUNAR_INFO[$year - self::MIN_YEAR]; if ($year === self::MIN_YEAR && $month <= 2 && $date <= 9) { return [1891, '正月', '初一', '辛卯', 1, 1, '兔']; } $dd = $this->getSolarMonthDays($year, $month); if ($this->isLeapYear($year) && $month === 2) { ++$dd; } $lunar_ary = []; for ($i = 1; $i < $dd; ++$i) { $array = $this->getLunarByBetween( @@ -94,24 +128,21 @@ public function convertSolarMonthToLunar(string $year, string $month): array /** * 將陰曆轉換為陽曆. * * @param int $year 陰曆-年 * @param int $month 陰曆-月,閏月處理:例如如果當年閏五月,那麼第二個五月就傳六月,相當於陰曆有13個月,只是有的時候第13個月的天數為0 * @param int $date 陰曆-日 * * @return array */ public function convertLunarToSolar(int $year, int $month, int $date): array { $yearData = self::LUNAR_INFO[$year - self::MIN_YEAR]; $between = $this->getDaysBetweenLunar($year, $month, $date); $res = mktime(0, 0, 0, $yearData[1], $yearData[2], $year); $res = date('Y-m-d', $res + $between * 24 * 60 * 60); return explode('-', $res); } /** @@ -123,22 +154,19 @@ public function convertLunarToSolar(string $year, string $month, string $date): */ public function isLeapYear(int $year): bool { return ($year & 3 === 0 && $year % 100 !== 0) || ($year % 400 === 0); } /** * 獲取干支紀年. * * @param int $year The year * * @return string the lunar year name */ public function getLunarYearName(int $year): string { return static::SKY[$year % 10] . static::EARTH[$year % 12]; } /** @@ -150,38 +178,22 @@ public function getLunarYearName(string $year): string */ public function getYearZodiac(int $year): string { return static::ZODIAC[$year % 12]; } /** * 獲取陽曆月份的天數. * * @param int $year 陽曆-年 * @param int $month 陽曆-月 * * @return int the solar month days */ public function getSolarMonthDays(int $year, int $month): int { return $month === 2 ? ($this->isLeapYear($year) ? 29 : 28) : static::MONTH_DAYS[$month]; } /** @@ -194,9 +206,7 @@ public function getSolarMonthDays(string $year, string $month) */ public function getLunarMonthDays(int $year, int $month): int { return $this->getLunarMonths($year)[$month - 1]; } /** @@ -211,13 +221,16 @@ public function getLunarMonths(int $year): array $yearData = self::LUNAR_INFO[$year - self::MIN_YEAR]; $leapMonth = $yearData[0]; $bit = decbin($yearData[3]); for ($i = 0; $i < strlen($bit); ++$i) { $bitArray[$i] = substr($bit, $i, 1); } for ($k = 0,$klen = 16 - count($bitArray); $k < $klen; ++$k) { array_unshift($bitArray, '0'); } $bitArray = array_slice($bitArray, 0, ($leapMonth === 0 ? 12 : 13)); for ($i = 0; $i < count($bitArray); ++$i) { $bitArray[$i] = $bitArray[$i] + 29; } @@ -238,7 +251,7 @@ public function getLunarYearDays(int $year): int $monthArray = $this->getLunarYearMonths($year); $len = count($monthArray); return $monthArray[$len - 1] === 0 ? $monthArray[$len - 2] : $monthArray[$len - 1]; } /** @@ -250,18 +263,19 @@ public function getLunarYearDays(int $year): int */ public function getLunarYearMonths(int $year): array { //debugger $monthData = $this->getLunarMonths($year); $res = []; $temp = 0; $yearData = self::LUNAR_INFO[$year - self::MIN_YEAR]; $len = ($yearData[0] === 0 ? 12 : 13); for ($i = 0; $i < $len; ++$i) { $temp = 0; for ($j = 0; $j <= $i; ++$j) { $temp += $monthData[$j]; } $res[] = $temp; } return $res; @@ -291,6 +305,7 @@ public function getLeapMonth(int $year): int public function getDaysBetweenLunar(int $year, int $month, int $date): int { $yearMonth = $this->getLunarMonths($year); $res = 0; for ($i = 1; $i < $month; ++$i) { $res += $yearMonth[$i - 1]; @@ -329,14 +344,15 @@ public function getDaysBetweenSolar(int $year, int $cmonth, int $cdate, int $dmo */ public function getLunarByBetween(int $year, int $between): array { // debugger $lunarArray = []; $yearMonth = []; $t = 0; $e = 0; $leapMonth = 0; $m = ''; if ($between === 0) { array_push($lunarArray, $year, '正月', '初一'); $t = 1; $e = 1; @@ -345,8 +361,9 @@ public function getLunarByBetween(int $year, int $between): array $yearMonth = $this->getLunarYearMonths($year); $leapMonth = $this->getLeapMonth($year); $between = $between > 0 ? $between : ($this->getLunarYearDays($year) + $between); for ($i = 0; $i < 13; ++$i) { if ($between === $yearMonth[$i]) { $t = $i + 2; $e = 1; break; @@ -357,46 +374,52 @@ public function getLunarByBetween(int $year, int $between): array break; } } $m = ($leapMonth !== 0 && $t === $leapMonth + 1) ? ('閏' . $this->getCapitalNum($t - 1, true)) : $this->getCapitalNum(($leapMonth !== 0 && $leapMonth + 1 < $t ? ($t - 1) : $t), true); array_push($lunarArray, $year, $m, $this->getCapitalNum($e, false)); } array_push( $lunarArray, $this->getLunarYearName($year), // 天干地支 $t, $e, $this->getYearZodiac($year), // 生肖 $leapMonth // 閏幾月 ); return $lunarArray; } /** * 獲取數字的陰曆叫法. * * @param int $num 數字 * @param bool $isMonth 是否是月份的數字 * * @return string the capital number */ public function getCapitalNum(int $num, bool $isMonth = false): string { if ($isMonth) { return static::MONTH_HASH[$num]; } if ($num <= 10) { $res = '初' . static::DATE_HASH[$num]; } elseif ($num < 20) { $res = '十' . static::DATE_HASH[$num - 10]; } elseif ($num === 20) { $res = '二十'; } elseif ($num < 30) { $res = '廿' . static::DATE_HASH[$num - 20]; } elseif ($num === 30) { $res = '三十'; } else { $res = ''; } return $res; -
jfcherng created this gist
Jan 1, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,408 @@ <?php class Lunar { const MIN_YEAR = 1891; const MAX_YEAR = 2100; const LUNAR_INFO = [ [0, 2, 9, 21936], [6, 1, 30, 9656], [0, 2, 17, 9584], [0, 2, 6, 21168], [5, 1, 26, 43344], [0, 2, 13, 59728], [0, 2, 2, 27296], [3, 1, 22, 44368], [0, 2, 10, 43856], [8, 1, 30, 19304], [0, 2, 19, 19168], [0, 2, 8, 42352], [5, 1, 29, 21096], [0, 2, 16, 53856], [0, 2, 4, 55632], [4, 1, 25, 27304], [0, 2, 13, 22176], [0, 2, 2, 39632], [2, 1, 22, 19176], [0, 2, 10, 19168], [6, 1, 30, 42200], [0, 2, 18, 42192], [0, 2, 6, 53840], [5, 1, 26, 54568], [0, 2, 14, 46400], [0, 2, 3, 54944], [2, 1, 23, 38608], [0, 2, 11, 38320], [7, 2, 1, 18872], [0, 2, 20, 18800], [0, 2, 8, 42160], [5, 1, 28, 45656], [0, 2, 16, 27216], [0, 2, 5, 27968], [4, 1, 24, 44456], [0, 2, 13, 11104], [0, 2, 2, 38256], [2, 1, 23, 18808], [0, 2, 10, 18800], [6, 1, 30, 25776], [0, 2, 17, 54432], [0, 2, 6, 59984], [5, 1, 26, 27976], [0, 2, 14, 23248], [0, 2, 4, 11104], [3, 1, 24, 37744], [0, 2, 11, 37600], [7, 1, 31, 51560], [0, 2, 19, 51536], [0, 2, 8, 54432], [6, 1, 27, 55888], [0, 2, 15, 46416], [0, 2, 5, 22176], [4, 1, 25, 43736], [0, 2, 13, 9680], [0, 2, 2, 37584], [2, 1, 22, 51544], [0, 2, 10, 43344], [7, 1, 29, 46248], [0, 2, 17, 27808], [0, 2, 6, 46416], [5, 1, 27, 21928], [0, 2, 14, 19872], [0, 2, 3, 42416], [3, 1, 24, 21176], [0, 2, 12, 21168], [8, 1, 31, 43344], [0, 2, 18, 59728], [0, 2, 8, 27296], [6, 1, 28, 44368], [0, 2, 15, 43856], [0, 2, 5, 19296], [4, 1, 25, 42352], [0, 2, 13, 42352], [0, 2, 2, 21088], [3, 1, 21, 59696], [0, 2, 9, 55632], [7, 1, 30, 23208], [0, 2, 17, 22176], [0, 2, 6, 38608], [5, 1, 27, 19176], [0, 2, 15, 19152], [0, 2, 3, 42192], [4, 1, 23, 53864], [0, 2, 11, 53840], [8, 1, 31, 54568], [0, 2, 18, 46400], [0, 2, 7, 46752], [6, 1, 28, 38608], [0, 2, 16, 38320], [0, 2, 5, 18864], [4, 1, 25, 42168], [0, 2, 13, 42160], [10, 2, 2, 45656], [0, 2, 20, 27216], [0, 2, 9, 27968], [6, 1, 29, 44448], [0, 2, 17, 43872], [0, 2, 6, 38256], [5, 1, 27, 18808], [0, 2, 15, 18800], [0, 2, 4, 25776], [3, 1, 23, 27216], [0, 2, 10, 59984], [8, 1, 31, 27432], [0, 2, 19, 23232], [0, 2, 7, 43872], [5, 1, 28, 37736], [0, 2, 16, 37600], [0, 2, 5, 51552], [4, 1, 24, 54440], [0, 2, 12, 54432], [0, 2, 1, 55888], [2, 1, 22, 23208], [0, 2, 9, 22176], [7, 1, 29, 43736], [0, 2, 18, 9680], [0, 2, 7, 37584], [5, 1, 26, 51544], [0, 2, 14, 43344], [0, 2, 3, 46240], [4, 1, 23, 46416], [0, 2, 10, 44368], [9, 1, 31, 21928], [0, 2, 19, 19360], [0, 2, 8, 42416], [6, 1, 28, 21176], [0, 2, 16, 21168], [0, 2, 5, 43312], [4, 1, 25, 29864], [0, 2, 12, 27296], [0, 2, 1, 44368], [2, 1, 22, 19880], [0, 2, 10, 19296], [6, 1, 29, 42352], [0, 2, 17, 42208], [0, 2, 6, 53856], [5, 1, 26, 59696], [0, 2, 13, 54576], [0, 2, 3, 23200], [3, 1, 23, 27472], [0, 2, 11, 38608], [11, 1, 31, 19176], [0, 2, 19, 19152], [0, 2, 8, 42192], [6, 1, 28, 53848], [0, 2, 15, 53840], [0, 2, 4, 54560], [5, 1, 24, 55968], [0, 2, 12, 46496], [0, 2, 1, 22224], [2, 1, 22, 19160], [0, 2, 10, 18864], [7, 1, 30, 42168], [0, 2, 17, 42160], [0, 2, 6, 43600], [5, 1, 26, 46376], [0, 2, 14, 27936], [0, 2, 2, 44448], [3, 1, 23, 21936], [0, 2, 11, 37744], [8, 2, 1, 18808], [0, 2, 19, 18800], [0, 2, 8, 25776], [6, 1, 28, 27216], [0, 2, 15, 59984], [0, 2, 4, 27424], [4, 1, 24, 43872], [0, 2, 12, 43744], [0, 2, 2, 37600], [3, 1, 21, 51568], [0, 2, 9, 51552], [7, 1, 29, 54440], [0, 2, 17, 54432], [0, 2, 5, 55888], [5, 1, 26, 23208], [0, 2, 14, 22176], [0, 2, 3, 42704], [4, 1, 23, 21224], [0, 2, 11, 21200], [8, 1, 31, 43352], [0, 2, 19, 43344], [0, 2, 7, 46240], [6, 1, 27, 46416], [0, 2, 15, 44368], [0, 2, 5, 21920], [4, 1, 24, 42448], [0, 2, 12, 42416], [0, 2, 2, 21168], [3, 1, 22, 43320], [0, 2, 9, 26928], [7, 1, 29, 29336], [0, 2, 17, 27296], [0, 2, 6, 44368], [5, 1, 26, 19880], [0, 2, 14, 19296], [0, 2, 3, 42352], [4, 1, 24, 21104], [0, 2, 10, 53856], [8, 1, 30, 59696], [0, 2, 18, 54560], [0, 2, 7, 55968], [6, 1, 27, 27472], [0, 2, 15, 22224], [0, 2, 5, 19168], [4, 1, 25, 42216], [0, 2, 12, 42192], [0, 2, 1, 53584], [2, 1, 21, 55592], [0, 2, 9, 54560], ]; /** * 將陽曆轉換為陰曆. * * @param year 公曆-年 * @param month 公曆-月 * @param date 公曆-日 * @param mixed $year * @param mixed $month * @param mixed $date */ public function convertSolarToLunar(string $year, string $month, string $date): array { //debugger; $yearData = self::LUNAR_INFO[$year - self::MIN_YEAR]; if ($year == self::MIN_YEAR && $month <= 2 && $date <= 9) { return [1891, '正月', '初一', '辛卯', 1, 1, '兔']; } return $this->getLunarByBetween( $year, $this->getDaysBetweenSolar($year, $month, $date, $yearData[1], $yearData[2]) ); } public function convertSolarMonthToLunar(string $year, string $month): array { $yearData = self::LUNAR_INFO[$year - self::MIN_YEAR]; if ($year == self::MIN_YEAR && $month <= 2 && $date <= 9) { return [1891, '正月', '初一', '辛卯', 1, 1, '兔']; } $month_days_ary = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; $dd = $month_days_ary[$month]; if ($this->isLeapYear($year) && $month == 2) { ++$dd; } $lunar_ary = []; for ($i = 1; $i < $dd; ++$i) { $array = $this->getLunarByBetween( $year, $this->getDaysBetweenSolar($year, $month, $i, $yearData[1], $yearData[2]) ); $array[] = $year . '-' . $month . '-' . $i; $lunar_ary[$i] = $array; } return $lunar_ary; } /** * 將陰曆轉換為陽曆. * * @param string $year 陰曆-年 * @param string $month 陰曆-月,閏月處理:例如如果當年閏五月,那麼第二個五月就傳六月,相當於陰曆有13個月,只是有的時候第13個月的天數為0 * @param string $date 陰曆-日 * * @return array */ public function convertLunarToSolar(string $year, string $month, string $date): array { $yearData = self::LUNAR_INFO[$year - self::MIN_YEAR]; $between = $this->getDaysBetweenLunar($year, $month, $date); $res = mktime(0, 0, 0, $yearData[1], $yearData[2], $year); $res = date('Y-m-d', $res + $between * 24 * 60 * 60); $day = explode('-', $res); $year = $day[0]; $month = $day[1]; $day = $day[2]; return [$year, $month, $day]; } /** * 判斷是否是閏年. * * @param int $year The year * * @return bool true if leap year, False otherwise */ public function isLeapYear(int $year): bool { return ($year & 3 == 0 && $year % 100 != 0) || ($year % 400 == 0); } /** * 獲取干支紀年. * * @param string $year The year * * @return string the lunar year name */ public function getLunarYearName(string $year): string { $sky = ['庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己']; $earth = ['申', '酉', '戌', '亥', '子', '丑', '寅', '卯', '辰', '巳', '午', '未']; return $sky[$year[3]] . $earth[$year % 12]; } /** * 根據陰曆年獲取生肖. * * @param int $year 陰曆年 * * @return array the year zodiac */ public function getYearZodiac(int $year): string { $zodiac = ['猴', '雞', '狗', '豬', '鼠', '牛', '虎', '兔', '龍', '蛇', '馬', '羊']; return $zodiac[$year % 12]; } /** * 獲取陽曆月份的天數. * * @param year 陽曆-年 * @param month 陽曆-月 * @param mixed $year * @param mixed $month */ public function getSolarMonthDays(string $year, string $month) { static $monthHash = [ '1' => 31, '3' => 31, '4' => 30, '5' => 31, '6' => 30, '7' => 31, '8' => 31, '9' => 30, '10' => 31, '11' => 30, '12' => 31, ]; return $month == '2' ? ($this->isLeapYear($year) ? 29 : 28) : $monthHash[$month]; } /** * 獲取陰曆月份的天數. * * @param int $year 陰曆-年 * @param int $month 陰曆-月,從一月開始 * * @return int the lunar month days */ public function getLunarMonthDays(int $year, int $month): int { $monthData = $this->getLunarMonths($year); return $monthData[$month - 1]; } /** * 獲取陰曆每月的天數的數組. * * @param int $year The year * * @return array the lunar months */ public function getLunarMonths(int $year): array { $yearData = self::LUNAR_INFO[$year - self::MIN_YEAR]; $leapMonth = $yearData[0]; $bit = decbin($yearData[3]); for ($i = 0; $i < strlen($bit); ++$i) { $bitArray[$i] = substr($bit, $i, 1); } for ($k = 0,$klen = 16 - count($bitArray); $k < $klen; ++$k) { array_unshift($bitArray, '0'); } $bitArray = array_slice($bitArray, 0, ($leapMonth == 0 ? 12 : 13)); for ($i = 0; $i < count($bitArray); ++$i) { $bitArray[$i] = $bitArray[$i] + 29; } return $bitArray; } /** * 獲取農曆每年的天數. * * @param int $year 農曆年份 * * @return int the lunar year days */ public function getLunarYearDays(int $year): int { $yearData = self::LUNAR_INFO[$year - self::MIN_YEAR]; $monthArray = $this->getLunarYearMonths($year); $len = count($monthArray); return $monthArray[$len - 1] == 0 ? $monthArray[$len - 2] : $monthArray[$len - 1]; } /** * 獲取農曆每年的月數. * * @param int $year The year * * @return array the lunar year months */ public function getLunarYearMonths(int $year): array { //debugger; $monthData = $this->getLunarMonths($year); $res = []; $temp = 0; $yearData = self::LUNAR_INFO[$year - self::MIN_YEAR]; $len = ($yearData[0] == 0 ? 12 : 13); for ($i = 0; $i < $len; ++$i) { $temp = 0; for ($j = 0; $j <= $i; ++$j) { $temp += $monthData[$j]; } array_push($res, $temp); } return $res; } /** * 獲取閏月. * * @param int $year 陰曆年份 * * @return int the leap month */ public function getLeapMonth(int $year): int { return self::LUNAR_INFO[$year - self::MIN_YEAR][0]; } /** * 計算陰曆日期與正月初一相隔的天數. * * @param int $year The year * @param int $month The month * @param int $date The date * * @return int the days between lunar */ public function getDaysBetweenLunar(int $year, int $month, int $date): int { $yearMonth = $this->getLunarMonths($year); $res = 0; for ($i = 1; $i < $month; ++$i) { $res += $yearMonth[$i - 1]; } $res += $date - 1; return $res; } /** * 計算2個陽曆日期之間的天數. * * @param int $year 陽曆年 * @param int $cmonth The cmonth * @param int $cdate The cdate * @param int $dmonth 陰曆正月對應的陽曆月份 * @param int $ddate 陰曆初一對應的陽曆天數 * * @return int the days between solar */ public function getDaysBetweenSolar(int $year, int $cmonth, int $cdate, int $dmonth, int $ddate): int { $a = mktime(0, 0, 0, $cmonth, $cdate, $year); $b = mktime(0, 0, 0, $dmonth, $ddate, $year); return ceil(($a - $b) / 24 / 3600); } /** * 根據距離正月初一的天數計算陰曆日期 * * @param int $year 陽曆年 * @param int $between 天數 * * @return array the lunar by between */ public function getLunarByBetween(int $year, int $between): array { //debugger; $lunarArray = []; $yearMonth = []; $t = 0; $e = 0; $leapMonth = 0; $m = ''; if ($between == 0) { array_push($lunarArray, $year, '正月', '初一'); $t = 1; $e = 1; } else { $year = $between > 0 ? $year : ($year - 1); $yearMonth = $this->getLunarYearMonths($year); $leapMonth = $this->getLeapMonth($year); $between = $between > 0 ? $between : ($this->getLunarYearDays($year) + $between); for ($i = 0; $i < 13; ++$i) { if ($between == $yearMonth[$i]) { $t = $i + 2; $e = 1; break; } if ($between < $yearMonth[$i]) { $t = $i + 1; $e = $between - (empty($yearMonth[$i - 1]) ? 0 : $yearMonth[$i - 1]) + 1; break; } } $m = ($leapMonth != 0 && $t == $leapMonth + 1) ? ('閏' . $this->getCapitalNum($t - 1, true)) : $this->getCapitalNum(($leapMonth != 0 && $leapMonth + 1 < $t ? ($t - 1) : $t), true); array_push($lunarArray, $year, $m, $this->getCapitalNum($e, false)); } array_push($lunarArray, $this->getLunarYearName($year)); // 天干地支 array_push($lunarArray, $t, $e); array_push($lunarArray, $this->getYearZodiac($year)); // 生肖 array_push($lunarArray, $leapMonth); // 閏幾月 return $lunarArray; } /** * 獲取數字的陰曆叫法. * * @param string $num 數字 * @param bool $isMonth 是否是月份的數字 * * @return string the capital number */ public function getCapitalNum(string $num, bool $isMonth = false): string { $dateHash = ['0' => '', '1' => '一', '2' => '二', '3' => '三', '4' => '四', '5' => '五', '6' => '六', '7' => '七', '8' => '八', '9' => '九', '10' => '十 ']; $monthHash = ['0' => '', '1' => '正月', '2' => '二月', '3' => '三月', '4' => '四月', '5' => '五月', '6' => '六月', '7' => '七月', '8' => '八月', '9' => '九月', '10' => '十月', '11' => '冬月', '12' => '臘月']; $res = ''; if ($isMonth) { $res = $monthHash[$num]; } else { if ($num <= 10) { $res = '初' . $dateHash[$num]; } elseif ($num > 10 && $num < 20) { $res = '十' . $dateHash[$num - 10]; } elseif ($num == 20) { $res = '二十'; } elseif ($num > 20 && $num < 30) { $res = '廿' . $dateHash[$num - 20]; } elseif ($num == 30) { $res = '三十'; } } return $res; } } $lunar = new Lunar(); $month = $lunar->convertSolarToLunar(2018, 1, 2); print_r($month);