Bạn đang tìm một code để chuyển đổi từ ngày âm lịch sang ngày dương lịch và ngược lại? Khi bạn đọc đến đây chắc chắn bạn tìm đúng chỗ rồi đó. Ngay bên dưới đây là code giúp bạn thực hiện việc chuyển đổi qua lại này. Bạn chỉ cần sử dụng 2 hàm là convertSolar2Lunar – để chuyển từ dương lịch sang âm lịch hoặc convertLunar2Solar – để chuyển ngày âm lịch sang dương lịch nhé.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
<?php class Duong2amlich { public function INT( $d ) { return floor( $d ) ; } public function jdFromDate( $dd, $mm, $yy ) { $a = $this::INT( ( 14 - $mm ) / 12 ) ; $y = $yy + 4800 - $a ; $m = $mm + 12 * $a - 3 ; $jd = $dd + $this::INT( ( 153 * $m + 2 ) / 5 ) + 365 * $y + $this::INT( $y / 4 ) - $this::INT( $y / 100 ) + $this::INT( $y / 400 ) - 32045 ; if ( $jd < 2299161 ) { $jd = $dd + $this::INT( ( 153 * $m + 2 ) / 5 ) + 365 * $y + $this::INT( $y / 4 ) - 32083 ; } return $jd ; } public function jdToDate( $jd ) { if ( $jd > 2299160 ) { // After 5/10/1582, Gregorian calendar $a = $jd + 32044 ; $b = $this::INT( ( 4 * $a + 3 ) / 146097 ) ; $c = $a - $this::INT( ( $b * 146097 ) / 4 ) ; } else { $b = 0 ; $c = $jd + 32082 ; } $d = $this::INT( ( 4 * $c + 3 ) / 1461 ) ; $e = $c - $this::INT( ( 1461 * $d ) / 4 ) ; $m = $this::INT( ( 5 * $e + 2 ) / 153 ) ; $day = $e - $this::INT( ( 153 * $m + 2 ) / 5 ) + 1 ; $month = $m + 3 - 12 * $this::INT( $m / 10 ) ; $year = $b * 100 + $d - 4800 + $this::INT( $m / 10 ) ; //echo "day = $day, month = $month, year = $year\n"; return array( $day, $month, $year ); } public function getNewMoonDay( $k, $timeZone ) { $T = $k / 1236.85; // Time in Julian centuries from 1900 January 0.5 $T2 = $T * $T; $T3 = $T2 * $T; $dr = M_PI / 180; $Jd1 = 2415020.75933 + 29.53058868 * $k + 0.0001178 * $T2 - 0.000000155 * $T3; $Jd1 = $Jd1 + 0.00033 * sin( ( 166.56 + 132.87 * $T - 0.009173 * $T2 ) * $dr); // Mean new moon $M = 359.2242 + 29.10535608 * $k - 0.0000333 * $T2 - 0.00000347 * $T3; // Sun's mean anomaly $Mpr = 306.0253 + 385.81691806 * $k + 0.0107306 * $T2 + 0.00001236 * $T3; // Moon's mean anomaly $F = 21.2964 + 390.67050646 * $k - 0.0016528 * $T2 - 0.00000239 * $T3; // Moon's argument of latitude $C1 = ( 0.1734 - 0.000393 * $T ) * sin( $M * $dr ) + 0.0021 * sin( 2 * $dr * $M ); $C1 = $C1 - 0.4068 * sin( $Mpr * $dr ) + 0.0161 * sin( $dr * 2 * $Mpr); $C1 = $C1 - 0.0004 * sin( $dr * 3 * $Mpr); $C1 = $C1 + 0.0104 * sin( $dr * 2 * $F ) - 0.0051 * sin( $dr * ( $M + $Mpr)); $C1 = $C1 - 0.0074 * sin( $dr * ( $M - $Mpr ) ) + 0.0004 * sin( $dr * ( 2 * $F + $M )); $C1 = $C1 - 0.0004 * sin( $dr * ( 2 * $F - $M ) ) - 0.0006 * sin( $dr * ( 2 * $F + $Mpr )); $C1 = $C1 + 0.0010 * sin( $dr * ( 2 * $F - $Mpr ) ) + 0.0005 * sin( $dr * ( 2 * $Mpr + $M )); if ( $T < -11 ) { $deltat = 0.001 + 0.000839 * $T + 0.0002261 * $T2 - 0.00000845 * $T3 - 0.000000081 * $T * $T3 ; } else { $deltat = -0.000278 + 0.000265 * $T + 0.000262 * $T2; } $JdNew = $Jd1 + $C1 - $deltat; //echo "JdNew = $JdNew\n"; return $this::INT( $JdNew + 0.5 + $timeZone / 24 ); } public function getSunLongitude( $jdn, $timeZone ) { $T = ( $jdn - 2451545.5 - $timeZone / 24 ) / 36525; // Time in Julian centuries from 2000-01-01 12:00:00 GMT $T2 = $T * $T; $dr = M_PI / 180; // degree to radian $M = 357.52910 + 35999.05030 * $T - 0.0001559 * $T2 - 0.00000048 * $T * $T2; // mean anomaly, degree $L0 = 280.46645 + 36000.76983 * $T + 0.0003032 * $T2; // mean longitude, degree $DL = ( 1.914600 - 0.004817 * $T - 0.000014 * $T2 ) * sin( $dr * $M ); $DL = $DL + ( 0.019993 - 0.000101 * $T ) * sin( $dr * 2 * $M ) + 0.000290 * sin( $dr * 3 * $M ); $L = $L0 + $DL; // true longitude, degree //echo "\ndr = $dr, M = $M, T = $T, DL = $DL, L = $L, L0 = $L0\n"; // obtain apparent longitude by correcting for nutation and aberration $omega = 125.04 - 1934.136 * $T; $L = $L - 0.00569 - 0.00478 * sin( $omega * $dr ); $L = $L * $dr; $L = $L - M_PI * 2 * ( $this::INT( $L / ( M_PI * 2 ) ) ); // Normalize to (0, 2*PI) return $this::INT( $L / M_PI * 6 ); } public function getLunarMonth11( $yy, $timeZone ) { $off = $this->jdFromDate( 31, 12, $yy ) - 2415021; $k = $this::INT( $off / 29.530588853 ); $nm = $this::getNewMoonDay( $k, $timeZone ); $sunLong = $this::getSunLongitude( $nm, $timeZone ); // sun longitude at local midnight if ( $sunLong >= 9 ) { $nm = $this::getNewMoonDay( $k - 1, $timeZone ); } return $nm; } public function getLeapMonthOffset( $a11, $timeZone ) { $k = $this::INT( ( $a11 - 2415021.076998695 ) / 29.530588853 + 0.5 ); $last = 0; $i = 1; // We start with the month following lunar month 11 $arc = $this::getSunLongitude( $this::getNewMoonDay( $k + $i, $timeZone ), $timeZone ); do { $last = $arc; $i = $i + 1; $arc = $this::getSunLongitude( $this::getNewMoonDay( $k + $i, $timeZone ), $timeZone ); } while ( $arc != $last && $i < 14 ); return $i - 1 ; } /* Comvert solar date dd/mm/yyyy to the corresponding lunar date */ public function convertSolar2Lunar( $dd, $mm, $yy, $timeZone ) { $dayNumber = $this::jdFromDate( $dd, $mm, $yy ); $k = $this::INT( ( $dayNumber - 2415021.076998695 ) / 29.530588853 ); $monthStart = $this::getNewMoonDay( $k + 1, $timeZone ); if ($monthStart > $dayNumber) { $monthStart = $this::getNewMoonDay( $k, $timeZone ); } $a11 = $this::getLunarMonth11( $yy, $timeZone ) ; $b11 = $a11 ; if ( $a11 >= $monthStart ) { $lunarYear = $yy; $a11 = $this::getLunarMonth11( $yy - 1, $timeZone ); } else { $lunarYear = $yy + 1; $b11 = $this::getLunarMonth11( $yy + 1, $timeZone ); } $lunarDay = $dayNumber - $monthStart + 1 ; $diff = $this::INT( ( $monthStart - $a11 ) / 29 ) ; $lunarLeap = 0 ; $lunarMonth = $diff + 11 ; if ( $b11 - $a11 > 365 ) { $leapMonthDiff = $this::getLeapMonthOffset( $a11, $timeZone ) ; if ( $diff >= $leapMonthDiff ) { $lunarMonth = $diff + 10 ; if ( $diff == $leapMonthDiff ) { $lunarLeap = 1 ; } } } if ( $lunarMonth > 12 ) { $lunarMonth = $lunarMonth - 12 ; } if ( $lunarMonth >= 11 && $diff < 4 ) { $lunarYear -= 1 ; } return array( $lunarDay, $lunarMonth, $lunarYear, $lunarLeap ) ; } /* Convert a lunar date to the corresponding solar date */ public function convertLunar2Solar( $lunarDay, $lunarMonth, $lunarYear, $lunarLeap, $timeZone ) { if ( $lunarMonth < 11 ) { $a11 = $this::getLunarMonth11( $lunarYear - 1, $timeZone ) ; $b11 = $this::getLunarMonth11( $lunarYear, $timeZone ) ; } else { $a11 = $this::getLunarMonth11( $lunarYear, $timeZone ) ; $b11 = $this::getLunarMonth11( $lunarYear + 1, $timeZone ) ; } $k = $this::INT( 0.5 + ( $a11 - 2415021.076998695 ) / 29.530588853 ) ; $off = $lunarMonth - 11 ; if ( $off < 0 ) { $off += 12 ; } if ( $b11 - $a11 > 365 ) { $leapOff = $this::getLeapMonthOffset( $a11, $timeZone ) ; $leapMonth = $leapOff - 2 ; if ( $leapMonth < 0 ) { $leapMonth += 12 ; } if ( $lunarLeap != 0 && $lunarMonth != $leapMonth ) { return array( 0, 0, 0 ) ; } else if ( $lunarLeap != 0 || $off >= $leapOff ) { $off += 1 ; } } $monthStart = $this::getNewMoonDay( $k + $off, $timeZone ) ; return $this::jdToDate( $monthStart + $lunarDay - 1 ) ; } } ?> |
Bạn có thể thử nghiệm 2 hàm này ở hệ thống API của chúng tôi tại: https://api.nosomovo.xyz/convert nhé.
Nosomovo
Trên trang index phải thể hiện thế nào?
Sau đây tôi xin gửi bạn code ví vụ cho 2 trường hợp sử dụng trên nhé, 1 chuyển từ ngày âm lịch sang ngày dương lịch và 2 là chuyển ngày dương lịch thành ngày âm lịch:
$dateconverter=new Duong2amlich();
//1. Chuyển từ dương lịch sang âm lịch
$dl_ngay=13;
$dl_thang=11;
$dl_nam=2019;
$timezone='7.0';
$ngayamlich=$dateconverter->convertSolar2Lunar($dl_ngay, $dl_thang, $dl_nam, $timezone);
echo $ngayamlich; //để xem kết quả
//2. Chuyển từ âm lịch sang dương lịch
$al_ngay=17;
$al_thang=10;
$al_nam=2019;
$lathangnhuan=0; //nếu là tháng nhuận thì set giá trị là 1
$timezone='7.0';
$ngayduonglich=$dateconverter->convertLunar2Solar($al_ngay, $al_thang, $al_nam, $lathangnhuan,$timezone);
echo $ngayduonglich; //để xem kết quả