<div class='fixed-footer-btns show' id='fixed-footer-btns' style='line-height: 30px;'>
            <div class='holder-body' style="display: flex; justify-content: center; flex-wrap: wrap; background-color: rgba(220,220,220,.8); padding: 4px 10px;">
                <div style='padding-right: 15px;'>
                    共{{pages.count}}条,第{{pages.page}}/{{pages.pageCount}}页
                </div>
                <div>
                    <ul class='yiiPager'>
                        <li class='first' v-if='pages.pageCount>1'><a href='javascript:;' class='page-jumper' @click='gotoPage(1)'>首页</a></li>
                        <li class='previous' v-if='pages.page>1'><a href='javascript:;' class='page-jumper' @click='gotoPage(pages.page - 1)'>上一页</a></li>
                        <li class='page' :class='item.class' v-for='item in pageList'><a href='javascript:;' class='page-jumper' @click='gotoPage(item.page)'>{{item.page}}</a></li>
                        <li class='next' v-if='pages.page < pages.pageCount'><a href='javascript:;' class='page-jumper' @click='gotoPage(pages.page + 1)'>下一页</a></li>
                        <li class='last' v-if='pages.pageCount>1'><a href='javascript:;' class='page-jumper' @click='gotoPage(pages.pageCount)'>末页</a></li>
                    </ul>
                </div>
                <div class='input-group input-group-sm pageGoto margin-left-sm'>
                    <input ref='pagenum' @change='gotoPage()' type='text' class='form-control input-sm text-center' style="width: 60px;">
                    <div class='input-group-btn '>
                        <div class='btn btn-sm btn-default' @click='gotoPage()'>跳转</div>
                    </div>
                </div><!-- /input-group -->
                <div class='input-group pageGoto margin-left-sm'>
                    <select ref='pageSize' v-model="pages.pageSize" @change='gotoPage(1)' class='form-control input-sm text-center' style="width: 100px;">
                        <option value="10">10/页</option>
                        <option value="30">30/页</option>
                        <option value="50">50/页</option>
                        <option value="100">100/页</option>
                        <option value="200">200/页</option>
                        <option value="300">300/页</option>
                        <option value="500">500/页</option>
                        <option value="1000">1000/页</option>
                    </select>
                </div><!-- /input-group -->
            </div>
        </div>
new Vue({

...
            computed:{

                pageList(){
                    const {pages} = this
                    var res = []
                    var pageViewCount = 5; //显示当前分页前后的页码数
                    for (var i = pages.page - pageViewCount; i <= pages.page + pageViewCount; i++) {
                        if (i < 1 || i > pages.pageCount) {
                            continue;
                        }
                        res.push({
                            class: i == pages.page ? 'selected' : '',
                            page: i,
                        })
                    }
                    return res
                }
}
...

})

Element.getBoundingClientRect() 方法返回一个 DOMRect 对象,其提供了元素的大小及其相对于视口的位置。
参考文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect
参数:无。
返回值是一个 DOMRect 对象,是包含整个元素的最小矩形(包括 padding 和 border-width)。该对象使用 left、top、right、bottom、x、y、width 和 height 这几个以像素为单位的只读属性描述整个矩形的位置和大小。除了 width 和 height 以外的属性是相对于视图窗口的左上角来计算的。

element.getBoundingClientRect().width
element.getBoundingClientRect().height

通过向通义灵码扩展提问,AI自动生成的方式,由最初的“生成一个带界面的时钟程序”,再“添加一个倒计时功能”、“添加音乐播放”、“添加停止播放按钮”一步一步生成了最终的这个程序,现在的AI已经很牛B了

import time
import pygame
from tkinter import Tk, Label, Button, Entry, messagebox

# 一个倒计时计时器程序
# 这个程序使用阿里云【灵码】插件,一步一步优化由AI生成的
# VS code IDE的扩展中安装TONGYI lingma
class TimerClock:
    def __init__(self, master):
        self.master = master
        master.title("Timer Clock")

        pygame.mixer.init()  # 初始化pygame.mixer

        # 创建标签以显示时间
        self.clock_label = Label(master, font=("Arial", 80), bg="black", fg="white")
        self.clock_label.pack(fill="both", expand=1)

        # 创建输入框以输入定时器时长
        self.timer_entry = Entry(master)
        self.timer_entry.pack()

        # 创建按钮以设置/停止定时器
        self.timer_button = Button(master, text="Start Timer", command=self.toggle_timer)
        self.timer_button.pack()

        # 创建按钮以停止音乐
        self.stop_music_button = Button(master, text="Stop Music", command=self.stop_music)
        self.stop_music_button.pack()

        # 定时器相关变量
        self.timer_duration = None
        self.timer_start_time = None
        self.timer_running = False
        self.countdown_id = None  # 存储倒计时ID

        # 初始化并开始更新时间
        self.update_time()

    def toggle_timer(self):
        if not self.timer_running:
            try:
                self.timer_duration = int(self.timer_entry.get())
                if self.timer_duration is not None:
                    self.timer_start_time = time.time()
                    self.countdown_id = self.master.after(0, self.countdown)
                    self.timer_button.config(text="Stop Timer")
                    self.timer_running = True
            except ValueError:
                messagebox.showerror("Error", "Please enter a valid integer.")
        else:
            self.timer_running = False
            self.timer_button.config(text="Start Timer")
            self.master.after_cancel(self.countdown_id)
            self.countdown_id = None
            pygame.mixer.music.stop()

    def countdown(self):
        remaining_time = max(0, self.timer_duration - int(time.time() - self.timer_start_time))
        self.timer_button.config(text=f"Countdown: {remaining_time} sec")
        if remaining_time > 0:
            self.countdown_id = self.master.after(1000, self.countdown)
        else:
            self.timer_alert()

    def timer_alert(self):
        pygame.mixer.music.load('alarm.mp3')
        pygame.mixer.music.play(-1)  # 循环播放音乐
        self.timer_running = False
        self.timer_button.config(text="Start Timer")

    def stop_music(self):
        pygame.mixer.music.stop()
        self.timer_button.config(state='normal')

    def update_time(self):
        current_time = time.strftime("%H:%M:%S")
        self.clock_label.config(text=current_time)
        self.clock_label.after(1000, self.update_time)

if __name__ == "__main__":
    root = Tk()
    my_clock = TimerClock(root)
    root.mainloop()

www/server/panel/data/system.db
这个是面板的监控信息,删除的话以前的数据就不在了,如果您觉得没必要的话可以删除,删除后命令行执行bt 1命令重启下面板。
或者在控制面板,左侧菜单【监控】页面,点击【清理数据】,没必要的话关闭监控功能或者定期清理数据

阳历转农历
可实现查询阳历对应的农历信息,天干地支,12生肖,闰几月

<?php

class DayService
{
    var $MIN_YEAR  = 1891;
    var $MAX_YEAR  = 2100;
    var $lunarInfo = array(
        array(0, 2, 9, 21936), array(6, 1, 30, 9656), array(0, 2, 17, 9584), array(0, 2, 6, 21168), array(5, 1, 26, 43344), array(0, 2, 13, 59728),
        array(0, 2, 2, 27296), array(3, 1, 22, 44368), array(0, 2, 10, 43856), array(8, 1, 30, 19304), array(0, 2, 19, 19168), array(0, 2, 8, 42352),
        array(5, 1, 29, 21096), array(0, 2, 16, 53856), array(0, 2, 4, 55632), array(4, 1, 25, 27304), array(0, 2, 13, 22176), array(0, 2, 2, 39632),
        array(2, 1, 22, 19176), array(0, 2, 10, 19168), array(6, 1, 30, 42200), array(0, 2, 18, 42192), array(0, 2, 6, 53840), array(5, 1, 26, 54568),
        array(0, 2, 14, 46400), array(0, 2, 3, 54944), array(2, 1, 23, 38608), array(0, 2, 11, 38320), array(7, 2, 1, 18872), array(0, 2, 20, 18800),
        array(0, 2, 8, 42160), array(5, 1, 28, 45656), array(0, 2, 16, 27216), array(0, 2, 5, 27968), array(4, 1, 24, 44456), array(0, 2, 13, 11104),
        array(0, 2, 2, 38256), array(2, 1, 23, 18808), array(0, 2, 10, 18800), array(6, 1, 30, 25776), array(0, 2, 17, 54432), array(0, 2, 6, 59984),
        array(5, 1, 26, 27976), array(0, 2, 14, 23248), array(0, 2, 4, 11104), array(3, 1, 24, 37744), array(0, 2, 11, 37600), array(7, 1, 31, 51560),
        array(0, 2, 19, 51536), array(0, 2, 8, 54432), array(6, 1, 27, 55888), array(0, 2, 15, 46416), array(0, 2, 5, 22176), array(4, 1, 25, 43736),
        array(0, 2, 13, 9680), array(0, 2, 2, 37584), array(2, 1, 22, 51544), array(0, 2, 10, 43344), array(7, 1, 29, 46248), array(0, 2, 17, 27808),
        array(0, 2, 6, 46416), array(5, 1, 27, 21928), array(0, 2, 14, 19872), array(0, 2, 3, 42416), array(3, 1, 24, 21176), array(0, 2, 12, 21168),
        array(8, 1, 31, 43344), array(0, 2, 18, 59728), array(0, 2, 8, 27296), array(6, 1, 28, 44368), array(0, 2, 15, 43856), array(0, 2, 5, 19296),
        array(4, 1, 25, 42352), array(0, 2, 13, 42352), array(0, 2, 2, 21088), array(3, 1, 21, 59696), array(0, 2, 9, 55632), array(7, 1, 30, 23208),
        array(0, 2, 17, 22176), array(0, 2, 6, 38608), array(5, 1, 27, 19176), array(0, 2, 15, 19152), array(0, 2, 3, 42192), array(4, 1, 23, 53864),
        array(0, 2, 11, 53840), array(8, 1, 31, 54568), array(0, 2, 18, 46400), array(0, 2, 7, 46752), array(6, 1, 28, 38608), array(0, 2, 16, 38320),
        array(0, 2, 5, 18864), array(4, 1, 25, 42168), array(0, 2, 13, 42160), array(10, 2, 2, 45656), array(0, 2, 20, 27216), array(0, 2, 9, 27968),
        array(6, 1, 29, 44448), array(0, 2, 17, 43872), array(0, 2, 6, 38256), array(5, 1, 27, 18808), array(0, 2, 15, 18800), array(0, 2, 4, 25776),
        array(3, 1, 23, 27216), array(0, 2, 10, 59984), array(8, 1, 31, 27432), array(0, 2, 19, 23232), array(0, 2, 7, 43872), array(5, 1, 28, 37736),
        array(0, 2, 16, 37600), array(0, 2, 5, 51552), array(4, 1, 24, 54440), array(0, 2, 12, 54432), array(0, 2, 1, 55888), array(2, 1, 22, 23208),
        array(0, 2, 9, 22176), array(7, 1, 29, 43736), array(0, 2, 18, 9680), array(0, 2, 7, 37584), array(5, 1, 26, 51544), array(0, 2, 14, 43344),
        array(0, 2, 3, 46240), array(4, 1, 23, 46416), array(0, 2, 10, 44368), array(9, 1, 31, 21928), array(0, 2, 19, 19360), array(0, 2, 8, 42416),
        array(6, 1, 28, 21176), array(0, 2, 16, 21168), array(0, 2, 5, 43312), array(4, 1, 25, 29864), array(0, 2, 12, 27296), array(0, 2, 1, 44368),
        array(2, 1, 22, 19880), array(0, 2, 10, 19296), array(6, 1, 29, 42352), array(0, 2, 17, 42208), array(0, 2, 6, 53856), array(5, 1, 26, 59696),
        array(0, 2, 13, 54576), array(0, 2, 3, 23200), array(3, 1, 23, 27472), array(0, 2, 11, 38608), array(11, 1, 31, 19176), array(0, 2, 19, 19152),
        array(0, 2, 8, 42192), array(6, 1, 28, 53848), array(0, 2, 15, 53840), array(0, 2, 4, 54560), array(5, 1, 24, 55968), array(0, 2, 12, 46496),
        array(0, 2, 1, 22224), array(2, 1, 22, 19160), array(0, 2, 10, 18864), array(7, 1, 30, 42168), array(0, 2, 17, 42160), array(0, 2, 6, 43600),
        array(5, 1, 26, 46376), array(0, 2, 14, 27936), array(0, 2, 2, 44448), array(3, 1, 23, 21936), array(0, 2, 11, 37744), array(8, 2, 1, 18808),
        array(0, 2, 19, 18800), array(0, 2, 8, 25776), array(6, 1, 28, 27216), array(0, 2, 15, 59984), array(0, 2, 4, 27424), array(4, 1, 24, 43872),
        array(0, 2, 12, 43744), array(0, 2, 2, 37600), array(3, 1, 21, 51568), array(0, 2, 9, 51552), array(7, 1, 29, 54440), array(0, 2, 17, 54432),
        array(0, 2, 5, 55888), array(5, 1, 26, 23208), array(0, 2, 14, 22176), array(0, 2, 3, 42704), array(4, 1, 23, 21224), array(0, 2, 11, 21200),
        array(8, 1, 31, 43352), array(0, 2, 19, 43344), array(0, 2, 7, 46240), array(6, 1, 27, 46416), array(0, 2, 15, 44368), array(0, 2, 5, 21920),
        array(4, 1, 24, 42448), array(0, 2, 12, 42416), array(0, 2, 2, 21168), array(3, 1, 22, 43320), array(0, 2, 9, 26928), array(7, 1, 29, 29336),
        array(0, 2, 17, 27296), array(0, 2, 6, 44368), array(5, 1, 26, 19880), array(0, 2, 14, 19296), array(0, 2, 3, 42352), array(4, 1, 24, 21104),
        array(0, 2, 10, 53856), array(8, 1, 30, 59696), array(0, 2, 18, 54560), array(0, 2, 7, 55968), array(6, 1, 27, 27472), array(0, 2, 15, 22224),
        array(0, 2, 5, 19168), array(4, 1, 25, 42216), array(0, 2, 12, 42192), array(0, 2, 1, 53584), array(2, 1, 21, 55592), array(0, 2, 9, 54560)
    );

    /**
     * 将阳历转换为阴历
     * @param year 公历-年
     * @param month 公历-月
     * @param date 公历-日
     */
    function convertSolarToLunar($year, $month, $date)
    {
        //debugger;
        $yearData = $this->lunarInfo[$year - $this->MIN_YEAR];
        if ($year == $this->MIN_YEAR && $month <= 2 && $date <= 9) return array(1891, '正月', '初一', '辛卯', 1, 1, '兔');
        return $this->getLunarByBetween($year, $this->getDaysBetweenSolar($year, $month, $date, $yearData[1], $yearData[2]));
    }

    function convertSolarMonthToLunar($year, $month, $date)
    {
        $yearData = $this->lunarInfo[$year - $this->MIN_YEAR];
        if ($year == $this->MIN_YEAR && $month <= 2 && $date <= 9) return array(1891, '正月', '初一', '辛卯', 1, 1, '兔');
        $month_days_ary = array(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 = array();
        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 year 阴历-年
     * @param month 阴历-月,闰月处理:例如如果当年闰五月,那么第二个五月就传六月,相当于阴历有13个月,只是有的时候第13个月的天数为0
     * @param date 阴历-日
     */
    function convertLunarToSolar($year, $month, $date)
    {
        $yearData = $this->lunarInfo[$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 array($year, $month, $day);
    }

    /**
     * 判断是否是闰年
     * @param year
     */
    function isLeapYear($year)
    {
        return (($year % 4 == 0 && $year % 100 != 0) || ($year % 400 == 0));
    }

    /**
     * 获取干支纪年
     * @param year
     */
    function getLunarYearName($year)
    {
        $sky   = array('庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己');
        $earth = array('申', '酉', '戌', '亥', '子', '丑', '寅', '卯', '辰', '巳', '午', '未');
        $year  = $year . '';
        return $sky[$year{3}] . $earth[$year % 12];
    }

    /**
     * 根据阴历年获取生肖
     * @param year 阴历年
     */
    function getYearZodiac($year)
    {
        $zodiac = array('猴', '鸡', '狗', '猪', '鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊');
        return $zodiac[$year % 12];
    }

    /**
     * 获取阳历月份的天数
     * @param year 阳历-年
     * @param month 阳历-月
     */
    function getSolarMonthDays($year, $month)
    {
        $monthHash = array('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"];
    }

    /**
     * 获取阴历月份的天数
     * @param year 阴历-年
     * @param month 阴历-月,从一月开始
     */
    function getLunarMonthDays($year, $month)
    {
        $monthData = $this->getLunarMonths($year);
        return $monthData[$month - 1];
    }

    /**
     * 获取阴历每月的天数的数组
     * @param year
     */
    function getLunarMonths($year)
    {
        $yearData  = $this->lunarInfo[$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;
    }

    /**
     * 获取农历每年的天数
     * @param year 农历年份
     */
    function getLunarYearDays($year)
    {
        $yearData   = $this->lunarInfo[$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       = array();
        $temp      = 0;
        $yearData  = $this->lunarInfo[$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->lunarInfo[$year - $this->MIN_YEAR];
        return $yearData[0];
    }

    /**
     * 计算阴历日期与正月初一相隔的天数
     * @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;
    }

    /**
     * 计算2个阳历日期之间的天数
     * @param year 阳历年
     * @param cmonth
     * @param cdate
     * @param dmonth 阴历正月对应的阳历月份
     * @param ddate 阴历初一对应的阳历天数
     */
    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);
    }

    /**
     * 根据距离正月初一的天数计算阴历日期
     * @param year 阳历年
     * @param between 天数
     */
    function getLunarByBetween($year, $between)
    {
        //debugger;
        $lunarArray = array();
        $yearMonth  = array();
        $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;
    }

    /**
     * 获取数字的阴历叫法
     * @param num 数字
     * @param isMonth 是否是月份的数字
     */
    function getCapitalNum($num, $isMonth)
    {
        $isMonth   = $isMonth || false;
        $dateHash  = array('0' => '', '1' => '一', '2' => '二', '3' => '三', '4' => '四', '5' => '五', '6' => '六', '7' => '七', '8' => '八', '9' => '九', '10' => '十 ');
        $monthHash = array('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;
    }

    /*
     * 节气通用算法
     */
    function getJieQi($_year, $month, $day)
    {
        $year        = substr($_year, -2) + 0;
        $coefficient = array(
            array(5.4055, 2019, -1),//小寒
            array(20.12, 2082, 1),  //大寒
            array(3.87),            //立春
            array(18.74, 2026, -1), //雨水
            array(5.63),            //惊蛰
            array(20.646, 2084, 1), //春分
            array(4.81),            //清明
            array(20.1),            //谷雨
            array(5.52, 1911, 1),   //立夏
            array(21.04, 2008, 1),  //小满
            array(5.678, 1902, 1),  //芒种
            array(21.37, 1928, 1),  //夏至
            array(7.108, 2016, 1),  //小暑
            array(22.83, 1922, 1),  //大暑
            array(7.5, 2002, 1),    //立秋
            array(23.13),           //处暑
            array(7.646, 1927, 1),  //白露
            array(23.042, 1942, 1), //秋分
            array(8.318),           //寒露
            array(23.438, 2089, 1), //霜降
            array(7.438, 2089, 1),  //立冬
            array(22.36, 1978, 1),  //小雪
            array(7.18, 1954, 1),   //大雪
            array(21.94, 2021, -1)  //冬至
        );
        $term_name   = array(
            '小寒', '大寒', '立春', '雨水', '惊蛰', '春分', '清明', '谷雨',
            '立夏', '小满', '芒种', '夏至', '小暑', '大暑', '立秋', '处暑',
            '白露', '秋分', '寒露', '霜降', '立冬', '小雪', '大雪', '冬至');
        $idx1        = ($month - 1) * 2;
        $_leap_value = floor(($year - 1) / 4);
        $day1        = floor($year * 0.2422 + $coefficient[$idx1][0]) - $_leap_value;
        if (isset($coefficient[$idx1][1]) && $coefficient[$idx1][1] == $_year) $day1 += $coefficient[$idx1][2];
        $day2 = floor($year * 0.2422 + $coefficient[$idx1 + 1][0]) - $_leap_value;
        if (isset($coefficient[$idx1 + 1][1]) && $coefficient[$idx1 + 1][1] == $_year) $day1 += $coefficient[$idx1 + 1][2];
        //echo __FILE__.'->'.__LINE__.' $day1='.$day1,',$day2='.$day2.'<br/>'.chr(10);
        $data = array();
        if ($day < $day1) {
            $data['name1'] = $term_name[$idx1 - 1];
            $data['name2'] = $term_name[$idx1 - 1] . '后';
        } else if ($day == $day1) {
            $data['name1'] = $term_name[$idx1];
            $data['name2'] = $term_name[$idx1];
        } else if ($day > $day1 && $day < $day2) {
            $data['name1'] = $term_name[$idx1];
            $data['name2'] = $term_name[$idx1] . '后';
        } else if ($day == $day2) {
            $data['name1'] = $term_name[$idx1 + 1];
            $data['name2'] = $term_name[$idx1 + 1];
        } else if ($day > $day2) {
            $data['name1'] = $term_name[$idx1 + 1];
            $data['name2'] = $term_name[$idx1 + 1] . '后';
        }
        return $data;
    }

    /*
     * 获取节日:特殊的节日只能修改此函数来计算
     */
    function getFestival($today, $nl_info = false, $config = 1)
    {
        if ($config == 1) {
            $arr_lunar = array('01-01' => '春节', '01-15' => '元宵节', '02-02' => '二月二', '05-05' => '端午节', '07-07' => '七夕节', '08-15' => '中秋节', '09-09' => '重阳节',
                               '12-08' => '腊八节', '12-23' => '小年');
            $arr_solar = array('01-01' => '元旦', '02-14' => '情人节', '03-12' => '植树节', '04-01' => '愚人节', '05-01' => '劳动节', '06-01' => '儿童节', '10-01' => '国庆节',
                               '10-31' => '万圣节', '12-24' => '平安夜', '12-25' => '圣诞节');
        }//需要不同节日的,用不同的$config,然后配置$arr_lunar和$arr_solar
        $festivals = array();
        list($y, $m, $d) = explode('-', $today);
        if (!$nl_info) $nl_info = $this->convertSolarToLunar($y, intval($m), intval($d));
        if ($nl_info[7] > 0 && $nl_info[7] < $nl_info[4]) $nl_info[4] -= 1;
        $md_lunar = substr('0' . $nl_info[4], -2) . '-' . substr('0' . $nl_info[5], -2);
        $md_solar = substr_replace($today, '', 0, 5);
        isset($arr_lunar[$md_lunar]) ? array_push($festivals, $arr_lunar[$md_lunar]) : '';
        isset($arr_solar[$md_solar]) ? array_push($festivals, $arr_solar[$md_solar]) : '';
        $glweek = date('w', strtotime($today));  //0-6
        if ($m == 5 && ($d > 7) && ($d < 15) && ($glweek == 0)) array_push($festivals, '母亲节');
        if ($m == 6 && ($d > 14) && ($d < 22) && ($glweek == 0)) array_push($festivals, '父亲节');
        $jieqi = $this->getJieQi($y, $m, $d);
        if ($jieqi) array_push($festivals, $jieqi);
        return implode('/', $festivals);
    }

    /*
    * 获取当前时间属于哪个时辰
    @param int $time 时间戳
    */
    function getTheHour($h)
    {
        $d = $h;
        if ($d == 23 || $d == 0) {
            return '子时';
        } else if ($d == 1 || $d == 2) {
            return '丑时';
        } else if ($d == 3 || $d == 4) {
            return '寅时';
        } else if ($d == 5 || $d == 6) {
            return '卯时';
        } else if ($d == 7 || $d == 8) {
            return '辰时';
        } else if ($d == 9 || $d == 10) {
            return '巳时';
        } else if ($d == 11 || $d == 12) {
            return '午时';
        } else if ($d == 13 || $d == 14) {
            return '未时';
        } else if ($d == 15 || $d == 16) {
            return '申时';
        } else if ($d == 17 || $d == 18) {
            return '酉时';
        } else if ($d == 19 || $d == 20) {
            return '戌时';
        } else if ($d == 21 || $d == 22) {
            return '亥时';
        }
    }

}

日历表格

<?php

/**
 * 创建日历表格类
 */
class CalendarHelper
{

    /**
     * 创建一个日历表格
     * @param null|int $firstDayTimestamp
     * @param array $initMergeData 每个日期的自定义数据数组[], 不能用这几个键名(其值会被本方法覆盖):time,week,day,date,nongli,class
     * @return array
     */
    public static function createCalender($firstDayTimestamp=null, $initMergeData = [])
    {
        if (is_null($firstDayTimestamp)) $firstDayTimestamp = strtotime(date('Y/m/01'));
        $calendar = [];
        $weekFirst = date('N', $firstDayTimestamp); //1(表示星期一)到 7(表示星期天)
        $monthEnd = strtotime('+1 month', $firstDayTimestamp) -1;

        $c = new DayService();
        //补足前面的
        if (($ca = $weekFirst - 1) > 0) {
            while ($ca>0) {
                $_time      = strtotime("-{$ca} day", $firstDayTimestamp);
                $_date = date('Y-m-d', $_time);
                $dd = $c->convertSolarToLunar(date('Y', $_time), date('m', $_time), date('d', $_time));
                $calendar[$_date] = array_merge($initMergeData, [
                    'time'   => $_time,
                    'week'   => date('N', $_time),
                    'day'    => date('j', $_time),
                    'date'   => $_date,
                    'nongli' => $dd,
                    'class'  => 'prev'
                ]);
                $ca--;
            }
        }
        //当月
        $_start = $firstDayTimestamp; $lastTime = null;
        while ($_start < $monthEnd) {
            $lastTime = $_start;
            $_date = date('Y-m-d', $_start);
            $dd = $c->convertSolarToLunar(date('Y', $_start), date('m', $_start), date('d', $_start));
            $calendar[$_date] = array_merge($initMergeData, [
                'time'  => $_start,
                'week'  => date('N', $_start),
                'day'   => date('j', $_start),
                'date'  => $_date,
                'nongli'  => $dd,
                'class' => 'current'
            ]);
            $_start += 86400;
        }
        //补足后面的
        $weekFirst = date('N', $lastTime); //1(表示星期一)到 7(表示星期天)
        //补足前面的
        if (($ca = 7 - $weekFirst) > 0) {
            $i = 1;
            while ($i <= $ca) {
                $_time      = strtotime("+{$i} day", $lastTime);
                $_date = date('Y-m-d', $_time);
                $dd = $c->convertSolarToLunar(date('Y', $_time), date('m', $_time), date('d', $_time));
                $calendar[$_date] = array_merge($initMergeData, [
                    'time'  => $_time,
                    'week'  => date('N', $_time),
                    'day'   => date('j', $_time),
                    'date'  => $_date,
                    'nongli'  => $dd,
                    'class' => 'next'
                ]);
                $i++;
            }
        }

        return $calendar;
    }

}