There is a customer birthday field, which stores the customer's birthday, which may be in the Gregorian calendar or the lunar calendar. Later, birthday text messages will be used to wish.
Birthday field (timestamp) Whether it is lunar calendar (int 0 or 1)
Does PHP have a ready-made wheel to handle the lunar and solar calendars?
擁有18年軟件開(kāi)發(fā)和IT教學(xué)經(jīng)驗(yàn)。曾任多家上市公司技術(shù)總監(jiān)、架構(gòu)師、項(xiàng)目經(jīng)理、高級(jí)軟件工程師等職務(wù)。 網(wǎng)絡(luò)人氣名人講師,...
The solar and lunar calendars are so important. Just cross one and you can pull it out by storing the timestamp in the field. Then you can calculate the lunar calendar by writing a class to calculate it
<?php
/**
* [$MIN_YEAR 陰歷陽(yáng)歷轉(zhuǎn)換]
* @var integer
*/
class Lunar{
public $MIN_YEAR = 1891;
public $MAX_YEAR = 2100;
public $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],
];
/**
* 將陽(yáng)歷轉(zhuǎn)換為陰歷
* @param year 公歷-年
* @param month 公歷-月
* @param date 公歷-日
*/
function convertSolarToLunar( $time )
{
$time = explode('-', date( 'Y-m-d', $time ) );
$year = $time[0];
$month = $time[1];
$date = $time[2];
$yearData = $this->lunar_info[$year-$this->MIN_YEAR];
if($year == $this->MIN_YEAR && $month<=2 && $date<=9 ){
return[1891,'正月','初一','辛卯',1,1,'兔'];
}
return $this->getLunarByBetween($year,$this->getDaysBetweenSolar($year,$month,$date,$yearData[1],$yearData[2]));
}
function convertSolarMonthToLunar($year,$month){
$yearData=$this->lunar_info[$year-$this->MIN_YEAR];
if($year==$this->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;
}
/**
* 將陰歷轉(zhuǎn)換為陽(yáng)歷
* @param year 陰歷-年
* @param month 陰歷-月,閏月處理:例如如果當(dāng)年閏五月,那么第二個(gè)五月就傳六月,相當(dāng)于陰歷有13個(gè)月,只是有的時(shí)候第13個(gè)月的天數(shù)為0
* @param date 陰歷-日
*/
function convertLunarToSolar($year,$month,$date){
$yearData=$this->lunar_info[$year-$this->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 year
*/
function isLeapYear($year){
return (($year%4==0&&$year%100!=0)||($year%400==0));
}
/**
* 獲取干支紀(jì)年
* @param year
*/
function getLunarYearName($year){
$sky=['庚','辛','壬','癸','甲','乙','丙','丁','戊','己'];
$earth=['申','酉','戌','亥','子','丑','寅','卯','辰','巳','午','未'];
$year=$year.'';
return $sky[$year{3}].$earth[$year%12];
}
/**
* 根據(jù)陰歷年獲取生肖
* @param year 陰歷年
*/
function getYearZodiac($year){
$zodiac=['猴','雞','狗','豬','鼠','牛','虎','兔','龍','蛇','馬','羊'];
return $zodiac[$year%12];
}
/**
* 獲取陽(yáng)歷月份的天數(shù)
* @param year 陽(yáng)歷-年
* @param month 陽(yáng)歷-月
*/
function getSolarMonthDays($year,$month){
$monthHash=['1'=>31,'2'=>$this->isLeapYear($year)?29:28,'3'=>31,'4'=>30,'5'=>31,'6'=>30,'7'=>31,'8'=>31,'9'=>30,'10'=>31,'11'=>30,'12'=>31];
return $monthHash["$month"];
}
/**
* 獲取陰歷月份的天數(shù)
* @param year 陰歷-年
* @param month 陰歷-月,從一月開(kāi)始
*/
function getLunarMonthDays($year,$month){
$monthData=$this->getLunarMonths($year);
return $monthData[$month-1];
}
/**
* 獲取陰歷每月的天數(shù)的數(shù)組
* @param year
*/
function getLunarMonths($year){
$yearData=$this->lunar_info[$year-$this->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;
}
/**
* 獲取農(nóng)歷每年的天數(shù)
* @param year 農(nóng)歷年份
*/
function getLunarYearDays($year){
$yearData=$this->lunar_info[$year-$this->MIN_YEAR];
$monthArray=$this->getLunarYearMonths($year);
$len=count($monthArray);
return ($monthArray[$len-1]==0?$monthArray[$len-2]:$monthArray[$len-1]);
}
function getLunarYearMonths($year){//debugger;
$monthData=$this->getLunarMonths($year);
$res=[];
$temp=0;
$yearData=$this->lunar_info[$year-$this->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 year 陰歷年份
*/
function getLeapMonth($year){
$yearData=$this->lunar_info[$year-$this->MIN_YEAR];
return $yearData[0];
}
/**
* 計(jì)算陰歷日期與正月初一相隔的天數(shù)
* @param year
* @param month
* @param date
*/
function getDaysBetweenLunar($year,$month,$date){
$yearMonth=$this->getLunarMonths($year);
$res=0;
for($i=1;$i<$month;$i++){
$res+=$yearMonth[$i-1];
}
$res+=$date-1;
return $res;
}
/**
* 計(jì)算2個(gè)陽(yáng)歷日期之間的天數(shù)
* @param year 陽(yáng)歷年
* @param cmonth
* @param cdate
* @param dmonth 陰歷正月對(duì)應(yīng)的陽(yáng)歷月份
* @param ddate 陰歷初一對(duì)應(yīng)的陽(yáng)歷天數(shù)
*/
function getDaysBetweenSolar($year,$cmonth,$cdate,$dmonth,$ddate){
$a=mktime(0,0,0,$cmonth,$cdate,$year);
$b=mktime(0,0,0,$dmonth,$ddate,$year);
return ceil(($a-$b)/24/3600);
}
/**
* 根據(jù)距離正月初一的天數(shù)計(jì)算陰歷日期
* @param year 陽(yáng)歷年
* @param between 天數(shù)
*/
function getLunarByBetween($year,$between){//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;
}else 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));// 12生肖
array_push($lunarArray,$leapMonth);// 閏幾月
return $lunarArray;
}
/**
* 獲取數(shù)字的陰歷叫法
* @param num 數(shù)字
* @param isMonth 是否是月份的數(shù)字
*/
function getCapitalNum($num,$isMonth){
$isMonth=$isMonth||false;
$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];
}else if($num>10&&$num<20){
$res='十'.$dateHash[$num-10];
}else if($num==20){
$res="二十";
}else if($num>20&&$num<30){
$res="廿".$dateHash[$num-20];
}else if($num==30){
$res="三十";
}
}
return $res;
}
}
header("Content-Type:text/html;charset=utf-8");
$lunar = new Lunar();
$month = $lunar->convertSolarToLunar(time());//將陽(yáng)歷轉(zhuǎn)換為陰歷
var_dump($month);
// array (size=8)
// 0 => string '2017' (length=4)
// 1 => string '三月' (length=6)
// 2 => string '十三' (length=6)
// 3 => string '丁酉' (length=6)
// 4 => int 3
// 5 => float 13
// 6 => string '雞' (length=3)
// 7 => int 6