这几个月想写个主题,搞点与众不同的功能,想到有的博客刻意地在弱化事件属性,那我岂不是可以用农历表示。
在网上翻了好几天,没找到可以准确的转换的函数,要么报错,要么输出不准确。
既然有 AI,我就尝试用 AI 写函数,但是迭代了几十个版本,输出依然不准确,再换了好几个平台和版本后,迭代出一个转换准确的函数,就分享给大家,我是将这个函数集成到 wordpress 主题之中。
主函数
class LunarDateConverter {
// 农历数据
private $lunarInfo = array(
0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,
0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,
0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,
0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,
0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,
0x06ca0,0x0b550,0x15355,0x04da0,0x0a5d0,0x14573,0x052d0,0x0a9a8,0x0e950,0x06aa0,
0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,
0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,
0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,
0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,
0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,
0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,
0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,
0x05aa0,0x076a3,0x096d0,0x04bd7,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,
0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,
0x14b63
);
// 农历月份名称
private $lunarMonthName = array('','正月','二月','三月','四月','五月','六月','七月','八月','九月','十月','冬月','腊月');
// 农历日名称
private $lunarDayName = array(
'','初一','初二','初三','初四','初五','初六','初七','初八','初九','初十',
'十一','十二','十三','十四','十五','十六','十七','十八','十九','二十',
'廿一','廿二','廿三','廿四','廿五','廿六','廿七','廿八','廿九','三十'
);
// 天干数组
private $tianGan = array("甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸");
// 地支数组
private $diZhi = array("子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥");
//生肖数组
private $shenXiong = array("鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪");
/**
* 获取农历某一年的天数
*
* 将公历日期转换为农历日期
*
* @param string $gregorianDate 公历日期,格式为 Y-m-d
* @return string 农历日期,格式为 二零二五年(乙巳)四月初九
*/
public function gregorianToLunar($gregorianDate,$hasYear = true,$hastgdz = true,$hashours = true) {
// 解析公历日期
$date = strtotime($gregorianDate);
$year = intval(date('Y', $date));
$month = intval(date('m', $date));
$day = intval(date('d', $date));
$hour = intval(date('H', $date));
// 公历 1900 年 1 月 31 日为农历 1900 年正月初一
$startDate = strtotime('1900-01-31');
$offset = intval(($date - $startDate) / 86400);
$lunarYear = 1900;
while ($offset >= 0) {
$temp = $this->getLunarYearDays($lunarYear);
if ($offset < $temp) break;
$offset -= $temp;
$lunarYear++;
}
$lunarLeap = $this->getLunarLeapMonth($lunarYear);
$lunarLeapFlag = false;
$lunarMonth = 1;
while ($lunarMonth <= 12) {
if ($lunarLeap > 0 && $lunarMonth == ($lunarLeap + 1) && !$lunarLeapFlag) {
$days = $this->getLunarLeapDays($lunarYear);
$lunarLeapFlag = true;
} else {
$days = $this->getLunarMonthDays($lunarYear, $lunarMonth);
}
if ($offset < $days) break;
$offset -= $days;
if ($lunarLeapFlag && $lunarMonth == $lunarLeap) $lunarLeapFlag = false;
if ($lunarMonth == 12 && !$lunarLeapFlag) $lunarYear++;
$lunarMonth++;
}
$lunarDay = $offset + 1;
// 计算天干索引
$ganIndex = ($lunarYear - 4) % 10;
if ($ganIndex < 0) {
$ganIndex += 10;
}
// 计算地支索引
$zhiIndex = ($lunarYear - 4) % 12;
if ($zhiIndex < 0) {
$zhiIndex += 12;
}
//属相计算
$shenxiaoIndex = ($lunarYear - 1900) % 12;
if ($shenxiaoIndex < 0) {
$shenxiaoIndex += 12;
}
// 返回天干地支组合
$tianGandizhi = $this->tianGan[$ganIndex] . $this->diZhi[$zhiIndex].$this->shenXiong[$shenxiaoIndex];
// 转换年份为中文数字
$chineseYear = strtr($lunarYear, array(
'0' => '零', '1' => '一', '2' => '二', '3' => '三', '4' => '四',
'5' => '五', '6' => '六', '7' => '七', '8' => '八', '9' => '九'
));
return (($hasYear)?$chineseYear:'').(($hastgdz)?'['.$tianGandizhi.'年] ':'')
. $this->lunarMonthName[$lunarMonth]
. $this->lunarDayName[$lunarDay]
. ($hashours?$this->timeTodizhi($hour):'');
}
/**
* 获取农历某一年的天数
*
* @param int $year 农历年份
* @return int 农历某一年的天数
*/
private function getLunarYearDays($year) {
$sum = 348;
for ($i = 0x8000; $i > 0x8; $i >>= 1) {
if ($this->lunarInfo[$year - 1900] & $i) $sum += 1;
}
return $sum + $this->getLunarLeapDays($year);
}
/**
* 获取转化后的地支时辰
*
* @param int $hour 24 小时制时间
* @return int 地支时辰
*/
private function timeTodizhi($hour){
$hour = $hour % 24;//确保时间在0-23之间
$index = ($hour+1); // 2
$zhishi = ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"];
return $zhishi[$index%12].'时';
}
/**
* 获取农历某一年闰月的天数
*
* @param int $year 农历年份
* @return int 农历某一年闰月的天数,如果没有闰月则返回 0
*/
private function getLunarLeapDays($year) {
if ($this->getLunarLeapMonth($year)) {
return (($this->lunarInfo[$year - 1900] & 0x10000)? 30 : 29);
}
return 0;
}
/**
* 获取农历某一年的闰月是几月,如果没有闰月则返回 0
*
* @param int $year 农历年份
* @return int 农历某一年的闰月月份,如果没有闰月则返回 0
*/
private function getLunarLeapMonth($year) {
return ($this->lunarInfo[$year - 1900] & 0xf);
}
/**
* 获取农历某一年某一月的天数
*
* @param int $year 农历年份
* @param int $month 农历月份
* @return int 农历某一年某一月的天数
*/
private function getLunarMonthDays($year, $month) {
return (($this->lunarInfo[$year - 1900] & (0x10000 >> $month))? 30 : 29);
}
}
使用方式和参数
// 使用示例
$LunarDateConverter = new LunarDateConverter();
//gregorianToLunar($gregorianDate,$hasYear = true,$hastgdz = true,$hashours = true)
$LunarDateConverter->gregorianToLunar(时间戳,[是否显示年(默认显示)],[是否显示天干地支(默认显示)],[是否显示地支时辰(默认显示)])
$LunarDateConverter = new LunarDateConverter();
$lunarDate = $LunarDateConverter->gregorianToLunar('2024-01-15');
echo $lunarDate; // 输出:二零二四年(丙戌)正月初一
我封装了个函数在 wordpres 中使用,将下述函数和上面的主函数放到 wordpress 主题的 functions.php 中,
function lunar_data($d = null,$hasYear = true,$hastgdz = true,$hashours = true) {
$LunarDateConverter = new LunarDateConverter();
echo $LunarDateConverter->gregorianToLunar($d,$hasYear,$hastgdz,$hashours);
}
在稿件中使用
<?php lunar_data(get_the_time('Y-m-d H:m:s'),false); ?>
在评论中使用
<?php lunar_data(get_comment_time('Y-m-d h:m:s'),false,false);?>
函数转换的时间段为 从 1900 年到 2050 年(好像是 2050年之前,再往后也没意义)
ok,到此结束!如有问题,到我的博客去留言。