-- 欢迎使用万象拼音方案
-- @amzxyz
-- https://github.com/amzxyz/rime_wanxiang
------------------------------------
------wirting by 98wubi Group-------
------http://98wb.ys168.com/--------
-----万象新增节日候选,格式化问候语,重写农历倒计
-- *******农历节气计算部分
-- ========角度变换===============
local rad = 180 * 3600 / math.pi -- 每弧度的角秒数
local RAD = 180 / math.pi        -- 每弧度的角度数
function int2(v)                 -- 取整数部分
    v = math.floor(v)
    if v < 0 then
        return v + 1
    else
        return v
    end
end

function rad2mrad(v) -- 对超过0-2PI的角度转为0-2PI
    v = math.fmod(v, 2 * math.pi)
    if v < 0 then
        return v + 2 * math.pi
    else
        return v
    end
end

function rad2str(d, tim) -- 将弧度转为字串
    ---tim=0输出格式示例: -23°59' 48.23"
    ---tim=1输出格式示例:  18h 29m 44.52s
    local s = "+"
    local w1 = "°"
    w2 = "’"
    w3 = "”"
    if d < 0 then
        d = -d
        s = '-'
    end
    if tim ~= 0 then
        d = d * 12 / math.pi
        w1 = "h "
        w2 = "m "
        w3 = "s "
    else
        d = d * 180 / math.pi
    end
    local a = math.floor(d)
    d = (d - a) * 60
    local b = math.floor(d)
    d = (d - b) * 60
    local c = math.floor(d)
    d = (d - c) * 100
    d = math.floor(d + 0.5)
    if d >= 100 then
        d = d - 100
        c = c + 1
    end
    if c >= 60 then
        c = c - 60
        b = b + 1
    end
    if b >= 60 then
        b = b - 60
        a = a + 1
    end
    a = "   " + a
    b = "0" + b
    c = "0" + c
    d = "0" + d
    local alen = string.len(a)
    local blen = string.len(b)
    local clen = string.len(c)
    local dlen = string.len(d)
    s = s .. string.sub(a, alen - 3, alen) + w1
    s = s .. string.sub(b, blen - 2, blen) + w2
    s = s .. string.sub(c, clen - 2, clen) + "."
    s = s .. string.sub(d, dlen - 2, dlen) + w3
    return s
end

-- ================日历计算===============
local J2000 = 2451545 -- 2000年前儒略日数(2000-1-1 12:00:00格林威治平时)

local JDate = {       -- 日期元件
    Y = 2000,
    M = 1,
    D = 1,
    h = 12,
    m = 0,
    s = 0,
    dts = { -- 世界时与原子时之差计算表
        -4000, 108371.7, -13036.80, 392.000, 0.0000, -500, 17201.0, -627.82, 16.170, -0.3413, -150, 12200.6, -346.41, 5.403,
        -0.1593, 150, 9113.8, -328.13, -1.647, 0.0377, 500, 5707.5, -391.41, 0.915, 0.3145, 900, 2203.4, -283.45, 13.034,
        -0.1778, 1300, 490.1, -57.35, 2.085, -0.0072, 1600, 120.0, -9.81, -1.532, 0.1403, 1700, 10.2, -0.91, 0.510, -0.0370,
        1800, 13.4, -0.72, 0.202, -0.0193, 1830, 7.8, -1.81, 0.416, -0.0247, 1860, 8.3, -0.13, -0.406, 0.0292, 1880, -5.4,
        0.32, -0.183, 0.0173, 1900, -2.3, 2.06, 0.169, -0.0135, 1920, 21.2, 1.69, -0.304, 0.0167, 1940, 24.2, 1.22, -0.064,
        0.0031, 1960, 33.2, 0.51, 0.231, -0.0109, 1980, 51.0, 1.29, -0.026, 0.0032, 2000, 64.7, -1.66, 5.224, -0.2905, 2150,
        279.4, 732.95, 429.579, 0.0158, 6000 },
    deltatT = function(JDate, y) -- 计算世界时与原子时之差,传入年
        local i
        local d = JDate.dts
        for x = 1, 100, 5 do
            if y < d[x + 5] or x == 96 then
                i = x
                break
            end
        end

        local t1 = (y - d[i]) / (d[i + 5] - d[i]) * 10
        local t2 = t1 * t1
        local t3 = t2 * t1
        return d[i + 1] + d[i + 2] * t1 + d[i + 3] * t2 + d[i + 4] * t3
    end,
    deltatT2 = function(JDate, jd) -- 传入儒略日(J2000起算),计算UTC与原子时的差(单位:日)
        return JDate:deltatT(jd / 365.2425 + 2000) / 86400.0
    end,
    toJD = function(JDate, UTC) -- 公历转儒略日,UTC=1表示原日期是UTC
        local y = JDate.Y
        m = JDate.M
        n = 0 -- 取出年月
        if m <= 2 then
            m = m + 12
            y = y - 1
        end
        if JDate.Y * 372 + JDate.M * 31 + JDate.D >= 588829 then -- 判断是否为格里高利历日1582*372+10*31+15
            n = int2(y / 100)
            n = 2 - n + int2(n / 4)                              -- 加百年闰
        end
        n = n + int2(365.2500001 * (y + 4716))                   -- 加上年引起的偏移日数
        n = n + int2(30.6 * (m + 1)) + JDate.D                   -- 加上月引起的偏移日数及日偏移数
        n = n + ((JDate.s / 60 + JDate.m) / 60 + JDate.h) / 24 - 1524.5
        if (UTC == 1) then
            return n + JDate.deltatT2(n - J2000)
        end
        return n
    end,
    setFromJD = function(JDate, jd, UTC) -- 儒略日数转公历,UTC=1表示目标公历是UTC
        if UTC == 1 then
            jd = jd - JDate:deltatT2(jd - J2000)
        end
        jd = jd + 0.5
        local A = int2(jd)
        F = jd - A, D -- 取得日数的整数部份A及小数部分F
        if A > 2299161 then
            D = int2((A - 1867216.25) / 36524.25)
            A = A + 1 + D - int2(D / 4)
        end
        A = A + 1524                          -- 向前移4年零2个月
        JDate.Y = int2((A - 122.1) / 365.25)  -- 年
        D = A - int2(365.25 * JDate.Y)        -- 去除整年日数后余下日数
        JDate.M = int2(D / 30.6001)           -- 月数
        JDate.D = D - int2(JDate.M * 30.6001) -- 去除整月日数后余下日数
        JDate.Y = JDate.Y - 4716
        JDate.M = JDate.M - 1
        if JDate.M > 12 then
            JDate.M = JDate.M - 12
        end
        if JDate.M <= 2 then
            JDate.Y = JDate.Y + 1
        end
        -- 日的小数转为时分秒
        F = F * 24
        JDate.h = int2(F)
        F = F - JDate.h
        F = F * 60
        JDate.m = int2(F)
        F = F - JDate.m
        F = F * 60
        JDate.s = F
    end,

    setFromStr = function(JDate, s) -- 设置时间,参数例:"20000101 120000"或"20000101"
        JDate.Y = string.sub(s, 1, 4)
        JDate.M = string.sub(s, 5, 6)
        JDate.D = string.sub(s, 7, 8)
        JDate.h = string.sub(s, 10, 11)
        JDate.m = string.sub(s, 12, 13)
        JDate.s = string.sub(s, 14, 18)
    end,
    toStr = function(JDate) -- 日期转为串
        local Y = "     " .. JDate.Y
        local M = "0" .. JDate.M
        local D = "0" .. JDate.D
        local h = JDate.h
        local m = JDate.m
        local s = math.floor(JDate.s + .5)
        if s >= 60 then
            s = s - 60
            m = m + 1
        end
        if m >= 60 then
            m = m - 60
            h = h + 1
        end
        h = "0" .. h
        m = "0" .. m
        s = "0" .. s
        local Ylen = string.len(Y)
        local Mlen = string.len(M)
        local Dlen = string.len(D)
        local hlen = string.len(h)
        local mlen = string.len(m)
        local slen = string.len(s)
        Y = string.sub(Y, Ylen - 4, Ylen)
        M = string.sub(M, Mlen - 1, Mlen)
        D = string.sub(D, Dlen - 1, Dlen)
        h = string.sub(h, hlen - 1, hlen)
        m = string.sub(m, mlen - 1, mlen)
        s = string.sub(s, slen - 1, slen)
        return Y .. "-" .. M .. "-" .. D .. " " .. h .. ":" .. m .. ":" .. s
    end,

    JQ = function(JDate) -- 输出节气日期的秒数
        local t = {}
        t.year = JDate.Y
        t.month = JDate.M
        t.day = JDate.D
        t.hour = JDate.h
        t.min = JDate.m
        t.sec = math.floor(JDate.s + .5)
        if t.sec >= 60 then
            t.sec = t.sec - 60
            t.min = t.min + 1
        end
        if t.min >= 60 then
            t.min = t.min - 60
            t.hour = t.hour + 1
        end
        return os.time(t)
    end,

    Dint_dec = function(JDate, jd, shiqu, int_dec) -- 算出:jd转到当地UTC后,UTC日数的整数部分或小数部分
        -- 基于J2000力学时jd的起算点是12:00:00时,所以跳日时刻发生在12:00:00,这与日历计算发生矛盾
        -- 把jd改正为00:00:00起算,这样儒略日的跳日动作就与日期的跳日同步
        -- 改正方法为jd=jd+0.5-deltatT+shiqu/24
        -- 把儒略日的起点移动-0.5(即前移12小时)
        -- 式中shiqu是时区,北京的起算点是-8小时,shiqu取8
        local u = jd + 0.5 - JDate.deltatT2(jd) + shiqu / 24
        if int_dec ~= 0 then
            return math.floor(u)     -- 返回整数部分
        else
            return u - math.floor(u) -- 返回小数部分
        end
    end,

    d1_d2 = function(JDate, d1, d2) -- 计算两个日期的相差的天数,输入字串格式日期,如:"20080101"
        local Y = JDate.Y
        M = JDate.M
        D = JDate.D
        h = JDate.h
        m = JDate.m
        s = JDate.s -- 备份原来的数据
        JDate.setFromStr(string.sub(d1, 1, 8) + " 120000")
        local jd1 = JDate.toJD(0)
        JDate.setFromStr(string.sub(d2, 1, 8) + " 120000")
        local jd2 = JDate.toJD(0)

        JDate.Y = Y
        JDate.M = M
        JDate.D = D
        JDate.h = h
        JDate.m = m
        JDate.s = s -- 还原
        if jd1 > jd2 then
            return math.floor(jd1 - jd2 + .0001)
        else
            return -Math.floor(jd2 - jd1 + .0001)
        end
    end
}
-- =========黄赤交角及黄赤坐标变换===========
local hcjjB = { 84381.448, -46.8150, -0.00059, 0.001813 }                                   -- 黄赤交角系数表
local preceB = { 0, 50287.92262, 111.24406, 0.07699, -0.23479, -0.00178, 0.00018, 0.00001 } -- Date黄道上的岁差p

function hcjj1(t)                                                                           -- 返回黄赤交角(常规精度),短期精度很高
    local t1 = t / 36525
    t2 = t1 * t1
    t3 = t2 * t1
    return (hcjjB[1] + hcjjB[2] * t1 + hcjjB[3] * t2 + hcjjB[4] * t3) / rad
end

function HCconv(JW, E) -- 黄赤转换(黄赤坐标旋转)
    -- 黄道赤道坐标变换,赤到黄E取负
    local HJ = rad2mrad(JW[1])
    HW = JW[2]
    local sinE = math.sin(E)
    cosE = math.cos(E)
    local sinW = cosE * math.sin(HW) + sinE * math.cos(HW) * math.sin(HJ)
    local J = math.atan2(math.sin(HJ) * cosE - math.tan(HW) * sinE, math.cos(HJ))
    JW[1] = rad2mrad(J)
    JW[2] = math.asin(sinW)
end

function addPrece(jd, zb) -- 补岁差
    local i
    t = 1
    v = 0
    t1 = jd / 365250
    for i = 2, 8 do
        t = t * t1
        v = v + preceB[i] * t
    end
    zb[1] = rad2mrad(zb[1] + (v + 2.9965 * t1) / rad)
end

-- ===============光行差==================
local GXC_e = { 0.016708634, -0.000042037, -0.0000001267 }                                                              -- 离心率
local GXC_p = { 102.93735 / RAD, 1.71946 / RAD, 0.00046 / RAD }                                                         -- 近点
local GXC_l = { 280.4664567 / RAD, 36000.76982779 / RAD, 0.0003032028 / RAD, 1 / 49931000 / RAD, -1 / 153000000 / RAD } -- 太平黄经
local GXC_k = 20.49552 /
    rad                                                                                                                 -- 光行差常数
function addGxc(t, zb)                                                                                                  -- 恒星周年光行差计算(黄道坐标中)
    local t1 = t / 36525
    local t2 = t1 * t1
    local t3 = t2 * t1
    local t4 = t3 * t1
    local L = GXC_l[1] + GXC_l[2] * t1 + GXC_l[3] * t2 + GXC_l[4] * t3 + GXC_l[5] * t4
    local p = GXC_p[1] + GXC_p[2] * t1 + GXC_p[3] * t2
    local e = GXC_e[1] + GXC_e[2] * t1 + GXC_e[3] * t2
    local dL = L - zb[1]
    local dP = p - zb[1]
    zb[1] = zb[1] - (GXC_k * (math.cos(dL) - e * math.cos(dP)) / math.cos(zb[2]))
    zb[2] = zb[2] - (GXC_k * math.sin(zb[2]) * (math.sin(dL) - e * math.sin(dP)))
    -- log.info('aa', L,p,e,dL,dP,zb[1], zb[2])
    zb[1] = rad2mrad(zb[1])
end

-- ===============章动计算==================
local nutB = { -- 章动表
    2.1824391966, -33.757045954, 0.0000362262, 3.7340E-08, -2.8793E-10, -171996, -1742, 92025, 89, 3.5069406862,
    1256.663930738, 0.0000105845, 6.9813E-10, -2.2815E-10, -13187, -16, 5736, -31, 1.3375032491, 16799.418221925,
    -0.0000511866, 6.4626E-08, -5.3543E-10, -2274, -2, 977, -5, 4.3648783932, -67.514091907, 0.0000724525, 7.4681E-08,
    -5.7586E-10, 2062, 2, -895, 5, 0.0431251803, -628.301955171, 0.0000026820, 6.5935E-10, 5.5705E-11, -1426, 34, 54, -1,
    2.3555557435, 8328.691425719, 0.0001545547, 2.5033E-07, -1.1863E-09, 712, 1, -7, 0, 3.4638155059, 1884.965885909,
    0.0000079025, 3.8785E-11, -2.8386E-10, -517, 12, 224, -6, 5.4382493597, 16833.175267879, -0.0000874129, 2.7285E-08,
    -2.4750E-10, -386, -4, 200, 0, 3.6930589926, 25128.109647645, 0.0001033681, 3.1496E-07, -1.7218E-09, -301, 0, 129, -1,
    3.5500658664, 628.361975567, 0.0000132664, 1.3575E-09, -1.7245E-10, 217, -5, -95, 3 }

function nutation(t) -- 计算黄经章动及交角章动
    local d = {}
    d.Lon = 0
    d.Obl = 0
    t = t / 36525
    local i, c
    local t1 = t
    local t2 = t1 * t1
    local t3 = t2 * t1
    local t4 = t3 * t1
    local t5 = t4 * t1
    for i = 1, #nutB, 9 do
        c = nutB[i] + nutB[i + 1] * t1 + nutB[i + 2] * t2 + nutB[i + 3] * t3 + nutB[i + 4] * t4
        d.Lon = d.Lon + (nutB[i + 5] + nutB[i + 6] * t / 10) * math.sin(c) -- 黄经章动
        d.Obl = d.Obl + (nutB[i + 7] + nutB[i + 8] * t / 10) * math.cos(c) -- 交角章动
    end
    d.Lon = d.Lon / (rad * 10000)                                          -- 黄经章动
    d.Obl = d.Obl / (rad * 10000)                                          -- 交角章动
    return d
end

function nutationRaDec(t, zb) -- 本函数计算赤经章动及赤纬章动
    local Ra = zb[1]
    local Dec = zb[2]
    local E = hcjj1(t)
    local sinE = math.sin(E)
    local cosE = math.cos(E) -- 计算黄赤交角
    local d = nutation(t)    -- 计算黄经章动及交角章动
    local cosRa = math.cos(Ra)
    local sinRa = math.sin(Ra)
    local tanDec = math.tan(Dec)
    zb[1] = zb[1] + (cosE + sinE * sinRa * tanDec) * d.Lon - cosRa * tanDec * d.Obl -- 赤经章动
    zb[2] = zb[2] + sinE * cosRa * d.Lon + sinRa * d.Obl                            -- 赤纬章动
    zb[1] = rad2mrad(zb[1])
end

-- =================以下是月球及地球运动参数表===================
--[[***************************************
* 如果用记事本查看此代码,请在"格式"菜单中去除"自动换行"
* E10是关于地球的,格式如下:
*    它是一个数组,每3个数看作一条记录,每条记录的3个数记为A,B,C
*    rec=A*cos(B+C*t)  式中t是J2000起算的儒略千年数
*    每条记录的计算结果(即rec)取和即得地球的日心黄经的周期量L0
* E11格式如下: rec = A*cos*(B+C*t) *t,     取和后得泊松量L1
* E12格式如下: rec = A*cos*(B+C*t) *t*t,   取和后得泊松量L2
* E13格式如下: rec = A*cos*(B+C*t) *t*t*t, 取和后得泊松量L3
* 最后地球的地心黄经:L = L0+L1+L2+L3+...
* E20,E21,E22,E23...用于计算黄纬
* M10,M11等是关于月球的,参数的用法请阅读Mnn()函数
***************************************** --]]
-- 地球运动VSOP87参数
local E10 = { -- 黄经周期项
    1.75347045673, 0.00000000000, 0.0000000000, 0.03341656456, 4.66925680417, 6283.0758499914, 0.00034894275, 4.62610241759,
    12566.1516999828, 0.00003417571, 2.82886579606, 3.5231183490, 0.00003497056, 2.74411800971, 5753.3848848968,
    0.00003135896, 3.62767041758, 77713.7714681205, 0.00002676218, 4.41808351397, 7860.4193924392, 0.00002342687,
    6.13516237631, 3930.2096962196, 0.00001273166, 2.03709655772, 529.6909650946, 0.00001324292, 0.74246356352,
    11506.7697697936, 0.00000901855, 2.04505443513, 26.2983197998, 0.00001199167, 1.10962944315, 1577.3435424478,
    0.00000857223, 3.50849156957, 398.1490034082, 0.00000779786, 1.17882652114, 5223.6939198022, 0.00000990250,
    5.23268129594, 5884.9268465832, 0.00000753141, 2.53339053818, 5507.5532386674, 0.00000505264, 4.58292563052,
    18849.2275499742, 0.00000492379, 4.20506639861, 775.5226113240, 0.00000356655, 2.91954116867, 0.0673103028,
    0.00000284125, 1.89869034186, 796.2980068164, 0.00000242810, 0.34481140906, 5486.7778431750, 0.00000317087,
    5.84901952218, 11790.6290886588, 0.00000271039, 0.31488607649, 10977.0788046990, 0.00000206160, 4.80646606059,
    2544.3144198834, 0.00000205385, 1.86947813692, 5573.1428014331, 0.00000202261, 2.45767795458, 6069.7767545534,
    0.00000126184, 1.08302630210, 20.7753954924, 0.00000155516, 0.83306073807, 213.2990954380, 0.00000115132, 0.64544911683,
    0.9803210682, 0.00000102851, 0.63599846727, 4694.0029547076, 0.00000101724, 4.26679821365, 7.1135470008, 0.00000099206,
    6.20992940258, 2146.1654164752, 0.00000132212, 3.41118275555, 2942.4634232916, 0.00000097607, 0.68101272270,
    155.4203994342, 0.00000085128, 1.29870743025, 6275.9623029906, 0.00000074651, 1.75508916159, 5088.6288397668,
    0.00000101895, 0.97569221824, 15720.8387848784, 0.00000084711, 3.67080093025, 71430.6956181291, 0.00000073547,
    4.67926565481, 801.8209311238, 0.00000073874, 3.50319443167, 3154.6870848956, 0.00000078756, 3.03698313141,
    12036.4607348882, 0.00000079637, 1.80791330700, 17260.1546546904, 0.00000085803, 5.98322631256, 161000.6857376741,
    0.00000056963, 2.78430398043, 6286.5989683404, 0.00000061148, 1.81839811024, 7084.8967811152, 0.00000069627,
    0.83297596966, 9437.7629348870, 0.00000056116, 4.38694880779, 14143.4952424306, 0.00000062449, 3.97763880587,
    8827.3902698748, 0.00000051145, 0.28306864501, 5856.4776591154, 0.00000055577, 3.47006009062, 6279.5527316424,
    0.00000041036, 5.36817351402, 8429.2412664666, 0.00000051605, 1.33282746983, 1748.0164130670, 0.00000051992,
    0.18914945834, 12139.5535091068, 0.00000049000, 0.48735065033, 1194.4470102246, 0.00000039200, 6.16832995016,
    10447.3878396044, 0.00000035566, 1.77597314691, 6812.7668150860, 0.00000036770, 6.04133859347, 10213.2855462110,
    0.00000036596, 2.56955238628, 1059.3819301892, 0.00000033291, 0.59309499459, 17789.8456197850, 0.00000035954,
    1.70876111898, 2352.8661537718 }
local E11 = { -- 黄经泊松1项
    6283.31966747491, 0.00000000000, 0.0000000000, 0.00206058863, 2.67823455584, 6283.0758499914, 0.00004303430,
    2.63512650414, 12566.1516999828, 0.00000425264, 1.59046980729, 3.5231183490, 0.00000108977, 2.96618001993,
    1577.3435424478, 0.00000093478, 2.59212835365, 18849.2275499742, 0.00000119261, 5.79557487799, 26.2983197998,
    0.00000072122, 1.13846158196, 529.6909650946, 0.00000067768, 1.87472304791, 398.1490034082, 0.00000067327,
    4.40918235168, 5507.5532386674, 0.00000059027, 2.88797038460, 5223.6939198022, 0.00000055976, 2.17471680261,
    155.4203994342, 0.00000045407, 0.39803079805, 796.2980068164, 0.00000036369, 0.46624739835, 775.5226113240,
    0.00000028958, 2.64707383882, 7.1135470008, 0.00000019097, 1.84628332577, 5486.7778431750, 0.00000020844, 5.34138275149,
    0.9803210682, 0.00000018508, 4.96855124577, 213.2990954380, 0.00000016233, 0.03216483047, 2544.3144198834,
    0.00000017293, 2.99116864949, 6275.9623029906 }
local E12 = { -- 黄经泊松2项
    0.00052918870, 0.00000000000, 0.0000000000, 0.00008719837, 1.07209665242, 6283.0758499914, 0.00000309125, 0.86728818832,
    12566.1516999828, 0.00000027339, 0.05297871691, 3.5231183490, 0.00000016334, 5.18826691036, 26.2983197998,
    0.00000015752, 3.68457889430, 155.4203994342, 0.00000009541, 0.75742297675, 18849.2275499742, 0.00000008937,
    2.05705419118, 77713.7714681205, 0.00000006952, 0.82673305410, 775.5226113240, 0.00000005064, 4.66284525271,
    1577.3435424478 }
local E13 = { 0.00000289226, 5.84384198723, 6283.0758499914, 0.00000034955, 0.00000000000, 0.0000000000, 0.00000016819,
    5.48766912348, 12566.1516999828 }
local E14 = { 0.00000114084, 3.14159265359, 0.0000000000, 0.00000007717, 4.13446589358, 6283.0758499914, 0.00000000765,
    3.83803776214, 12566.1516999828 }
local E15 = { 0.00000000878, 3.14159265359, 0.0000000000 }
local E20 = { -- 黄纬周期项
    0.00000279620, 3.19870156017, 84334.6615813083, 0.00000101643, 5.42248619256, 5507.5532386674, 0.00000080445,
    3.88013204458, 5223.6939198022, 0.00000043806, 3.70444689758, 2352.8661537718, 0.00000031933, 4.00026369781,
    1577.3435424478, 0.00000022724, 3.98473831560, 1047.7473117547, 0.00000016392, 3.56456119782, 5856.4776591154,
    0.00000018141, 4.98367470263, 6283.0758499914, 0.00000014443, 3.70275614914, 9437.7629348870, 0.00000014304,
    3.41117857525, 10213.2855462110 }
local E21 = { 0.00000009030, 3.89729061890, 5507.5532386674, 0.00000006177, 1.73038850355, 5223.6939198022 }
local E30 = { -- 距离周期项
    1.00013988799, 0.00000000000, 0.0000000000, 0.01670699626, 3.09846350771, 6283.0758499914, 0.00013956023, 3.05524609620,
    12566.1516999828, 0.00003083720, 5.19846674381, 77713.7714681205, 0.00001628461, 1.17387749012, 5753.3848848968,
    0.00001575568, 2.84685245825, 7860.4193924392, 0.00000924799, 5.45292234084, 11506.7697697936, 0.00000542444,
    4.56409149777, 3930.2096962196 }
local E31 = { 0.00103018608, 1.10748969588, 6283.0758499914, 0.00001721238, 1.06442301418, 12566.1516999828,
    0.00000702215, 3.14159265359, 0.0000000000 }
local E32 = { 0.00004359385, 5.78455133738, 6283.0758499914 }
local E33 = { 0.00000144595, 4.27319435148, 6283.0758499914 }
-- 月球运动参数
local M10 = { 22639.5858800, 2.3555545723, 8328.6914247251, 1.5231275E-04, 2.5041111E-07, -1.1863391E-09, 4586.4383203,
    8.0413790709, 7214.0628654588, -2.1850087E-04, -1.8646419E-07, 8.7760973E-10, 2369.9139357, 10.3969336431,
    15542.7542901840, -6.6188121E-05, 6.3946925E-08, -3.0872935E-10, 769.0257187, 4.7111091445,
    16657.3828494503, 3.0462550E-04, 5.0082223E-07, -2.3726782E-09, -666.4175399, -0.0431256817,
    628.3019552485, -2.6638815E-06, 6.1639211E-10, -5.4439728E-11, -411.5957339, 3.2558104895,
    16866.9323152810, -1.2804259E-04, -9.8998954E-09, 4.0433461E-11, 211.6555524, 5.6858244986,
    -1114.6285592663, -3.7081362E-04, -4.3687530E-07, 2.0639488E-09, 205.4359530, 8.0845047526,
    6585.7609102104, -2.1583699E-04, -1.8708058E-07, 9.3204945E-10, 191.9561973, 12.7524882154,
    23871.4457149091, 8.6124629E-05, 3.1435804E-07, -1.4950684E-09, 164.7286185, 10.4400593249,
    14914.4523349355, -6.3524240E-05, 6.3330532E-08, -2.5428962E-10, -147.3213842, -2.3986802540,
    -7700.3894694766, -1.5497663E-04, -2.4979472E-07, 1.1318993E-09, -124.9881185, 5.1984668216,
    7771.3771450920, -3.3094061E-05, 3.1973462E-08, -1.5436468E-10, -109.3803637, 2.3124288905,
    8956.9933799736, 1.4964887E-04, 2.5102751E-07, -1.2407788E-09, 55.1770578, 7.1411231536, -1324.1780250970,
    6.1854469E-05, 7.3846820E-08, -3.4916281E-10, -45.0996092, 5.6113650618, 25195.6237400061, 2.4270161E-05,
    2.4051122E-07, -1.1459056E-09, 39.5333010, -0.9002559173, -8538.2408905558, 2.8035534E-04, 2.6031101E-07,
    -1.2267725E-09, 38.4298346, 18.4383127140, 22756.8171556428, -2.8468899E-04, -1.2251727E-07, 5.6888037E-10,
    36.1238141, 7.0666637168, 24986.0742741754, 4.5693825E-04, 7.5123334E-07, -3.5590172E-09, 30.7725751,
    16.0827581417, 14428.1257309177, -4.3700174E-04, -3.7292838E-07, 1.7552195E-09, -28.3971008, 7.9982533891,
    7842.3648207073, -2.2116475E-04, -1.8584780E-07, 8.2317000E-10, -24.3582283, 10.3538079614,
    16171.0562454324, -6.8852003E-05, 6.4563317E-08, -3.6316908E-10, -18.5847068, 2.8429122493,
    -557.3142796331, -1.8540681E-04, -2.1843765E-07, 1.0319744E-09, 17.9544674, 5.1553411398, 8399.6791003405,
    -3.5757942E-05, 3.2589854E-08, -2.0880440E-10, 14.5302779, 12.7956138971, 23243.1437596606, 8.8788511E-05,
    3.1374165E-07, -1.4406287E-09, 14.3796974, 15.1080427876, 32200.1371396342, 2.3843738E-04, 5.6476915E-07,
    -2.6814075E-09, 14.2514576, -24.0810366320, -2.3011998397, 1.5231275E-04, 2.5041111E-07, -1.1863391E-09,
    13.8990596, 20.7938672862, 31085.5085803679, -1.3237624E-04, 1.2789385E-07, -6.1745870E-10, 13.1940636,
    3.3302699264, -9443.3199839914, -5.2312637E-04, -6.8728642E-07, 3.2502879E-09, -9.6790568, -4.7542348263,
    -16029.0808942018, -3.0728938E-04, -5.0020584E-07, 2.3182384E-09, -9.3658635, 11.2971895604,
    24080.9951807398, -3.4654346E-04, -1.9636409E-07, 9.1804319E-10, 8.6055318, 5.7289501804, -1742.9305145148,
    -3.6814974E-04, -4.3749170E-07, 2.1183885E-09, -8.4530982, 7.5540213938, 16100.0685698171, 1.1921869E-04,
    2.8238458E-07, -1.3407038E-09, 8.0501724, 10.4831850066, 14286.1503796870, -6.0860358E-05, 6.2714140E-08,
    -1.9984990E-10, -7.6301553, 4.6679834628, 17285.6848046987, 3.0196162E-04, 5.0143862E-07, -2.4271179E-09,
    -7.4474952, -0.0862513635, 1256.6039104970, -5.3277630E-06, 1.2327842E-09, -1.0887946E-10, 7.3712011,
    8.1276304344, 5957.4589549619, -2.1317311E-04, -1.8769697E-07, 9.8648918E-10, 7.0629900, 0.9591375719,
    33.7570471374, -3.0829302E-05, -3.6967043E-08, 1.7385419E-10, -6.3831491, 9.4966777258, 7004.5133996281,
    2.1416722E-04, 3.2425793E-07, -1.5355019E-09, -5.7416071, 13.6527441326, 32409.6866054649, -1.9423071E-04,
    5.4047029E-08, -2.6829589E-10, 4.3740095, 18.4814383957, 22128.5152003943, -2.8202511E-04, -1.2313366E-07,
    6.2332010E-10, -3.9976134, 7.9669196340, 33524.3151647312, 1.7658291E-04, 4.9092233E-07, -2.3322447E-09,
    -3.2096876, 13.2398458924, 14985.4400105508, -2.5159493E-04, -1.5449073E-07, 7.2324505E-10, -2.9145404,
    12.7093625336, 24499.7476701576, 8.3460748E-05, 3.1497443E-07, -1.5495082E-09, 2.7318890, 16.1258838235,
    13799.8237756692, -4.3433786E-04, -3.7354477E-07, 1.8096592E-09, -2.5679459, -2.4418059357,
    -7072.0875142282, -1.5764051E-04, -2.4917833E-07, 1.0774596E-09, -2.5211990, 7.9551277074, 8470.6667759558,
    -2.2382863E-04, -1.8523141E-07, 7.6873027E-10, 2.4888871, 5.6426988169, -486.3266040178, -3.7347750E-04,
    -4.3625891E-07, 2.0095091E-09, 2.1460741, 7.1842488353, -1952.4799803455, 6.4518350E-05, 7.3230428E-08,
    -2.9472308E-10, 1.9777270, 23.1494218585, 39414.2000050930, 1.9936508E-05, 3.7830496E-07, -1.8037978E-09,
    1.9336825, 9.4222182890, 33314.7656989005, 6.0925100E-04, 1.0016445E-06, -4.7453563E-09, 1.8707647,
    20.8369929680, 30457.2066251194, -1.2971236E-04, 1.2727746E-07, -5.6301898E-10, -1.7529659, 0.4873576771,
    -8886.0057043583, -3.3771956E-04, -4.6884877E-07, 2.2183135E-09, -1.4371624, 7.0979974718, -695.8760698485,
    5.9190587E-05, 7.4463212E-08, -4.0360254E-10, -1.3725701, 1.4552986550, -209.5494658307, 4.3266809E-04,
    5.1072212E-07, -2.4131116E-09, 1.2618162, 7.5108957121, 16728.3705250656, 1.1655481E-04, 2.8300097E-07,
    -1.3951435E-09 }
local M11 = { 1.6768000, -0.0431256817, 628.3019552485, -2.6638815E-06, 6.1639211E-10, -5.4439728E-11, 0.5164200,
    11.2260974062, 6585.7609102104, -2.1583699E-04, -1.8708058E-07, 9.3204945E-10, 0.4138300, 13.5816519784,
    14914.4523349355, -6.3524240E-05, 6.3330532E-08, -2.5428962E-10, 0.3711500, 5.5402729076, 7700.3894694766,
    1.5497663E-04, 2.4979472E-07, -1.1318993E-09, 0.2756000, 2.3124288905, 8956.9933799736, 1.4964887E-04,
    2.5102751E-07, -1.2407788E-09, 0.2459863, -25.6198212459, -2.3011998397, 1.5231275E-04, 2.5041111E-07,
    -1.1863391E-09, 0.0711800, 7.9982533891, 7842.3648207073, -2.2116475E-04, -1.8584780E-07, 8.2317000E-10,
    0.0612800, 10.3538079614, 16171.0562454324, -6.8852003E-05, 6.4563317E-08, -3.6316908E-10 }
local M12 = { 0.0048700, -0.0431256817, 628.3019552485, -2.6638815E-06, 6.1639211E-10, -5.4439728E-11, 0.0022800,
    -27.1705318325, -2.3011998397, 1.5231275E-04, 2.5041111E-07, -1.1863391E-09, 0.0015000, 11.2260974062,
    6585.7609102104, -2.1583699E-04, -1.8708058E-07, 9.3204945E-10 }
local M20 = { 18461.2400600, 1.6279052448, 8433.4661576405, -6.4021295E-05, -4.9499477E-09, 2.0216731E-11, 1010.1671484,
    3.9834598170, 16762.1575823656, 8.8291456E-05, 2.4546117E-07, -1.1661223E-09, 999.6936555, 0.7276493275,
    -104.7747329154, 2.1633405E-04, 2.5536106E-07, -1.2065558E-09, 623.6524746, 8.7690283983, 7109.2881325435,
    -2.1668263E-06, 6.8896872E-08, -3.2894608E-10, 199.4837596, 9.6692843156, 15647.5290230993, -2.8252217E-04,
    -1.9141414E-07, 8.9782646E-10, 166.5741153, 6.4134738261, -1219.4032921817, -1.5447958E-04, -1.8151424E-07,
    8.5739300E-10, 117.2606951, 12.0248388879, 23976.2204478244, -1.3020942E-04, 5.8996977E-08, -2.8851262E-10,
    61.9119504, 6.3390143893, 25090.8490070907, 2.4060421E-04, 4.9587228E-07, -2.3524614E-09, 33.3572027,
    11.1245829706, 15437.9795572686, 1.5014592E-04, 3.1930799E-07, -1.5152852E-09, 31.7596709, 3.0832038997,
    8223.9166918098, 3.6864680E-04, 5.0577218E-07, -2.3928949E-09, 29.5766003, 8.8121540801, 6480.9861772950,
    4.9705523E-07, 6.8280480E-08, -2.7450635E-10, 15.5662654, 4.0579192538, -9548.0947169068, -3.0679233E-04,
    -4.3192536E-07, 2.0437321E-09, 15.1215543, 14.3803934601, 32304.9118725496, 2.2103334E-05, 3.0940809E-07,
    -1.4748517E-09, -12.0941511, 8.7259027166, 7737.5900877920, -4.8307078E-06, 6.9513264E-08, -3.8338581E-10,
    8.8681426, 9.7124099974, 15019.2270678508, -2.7985829E-04, -1.9203053E-07, 9.5226618E-10, 8.0450400,
    0.6687636586, 8399.7091105030, -3.3191993E-05, 3.2017096E-08, -1.5363746E-10, 7.9585542, 12.0679645696,
    23347.9184925760, -1.2754553E-04, 5.8380585E-08, -2.3407289E-10, 7.4345550, 6.4565995078, -1847.7052474301,
    -1.5181570E-04, -1.8213063E-07, 9.1183272E-10, -6.7314363, -4.0265854988, -16133.8556271171,
    -9.0955337E-05, -2.4484477E-07, 1.1116826E-09, 6.5795750, 16.8104074692, 14323.3509980023, -2.2066770E-04,
    -1.1756732E-07, 5.4866364E-10, -6.4600721, 1.5847795630, 9061.7681128890, -6.6685176E-05, -4.3335556E-09,
    -3.4222998E-11, -6.2964773, 4.8837157343, 25300.3984729215, -1.9206388E-04, -1.4849843E-08, 6.0650192E-11,
    -5.6323538, -0.7707750092, 733.0766881638, -2.1899793E-04, -2.5474467E-07, 1.1521161E-09, -5.3683961,
    6.8263720663, 16204.8433027325, -9.7115356E-05, 2.7023515E-08, -1.3414795E-10, -5.3112784, 3.9403341353,
    17390.4595376141, 8.5627574E-05, 2.4607756E-07, -1.2205621E-09, -5.0759179, 0.6845236457, 523.5272223331,
    2.1367016E-04, 2.5597745E-07, -1.2609955E-09, -4.8396143, -1.6710309265, -7805.1642023920, 6.1357413E-05,
    5.5663398E-09, -7.4656459E-11, -4.8057401, 3.5705615768, -662.0890125485, 3.0927234E-05, 3.6923410E-08,
    -1.7458141E-10, 3.9840545, 8.6945689615, 33419.5404318159, 3.9291696E-04, 7.4628340E-07, -3.5388005E-09,
    3.6744619, 19.1659620415, 22652.0424227274, -6.8354947E-05, 1.3284380E-07, -6.3767543E-10, 2.9984815,
    20.0662179587, 31190.2833132833, -3.4871029E-04, -1.2746721E-07, 5.8909710E-10, 2.7986413, -2.5281611620,
    -16971.7070481963, 3.4437664E-04, 2.6526096E-07, -1.2469893E-09, 2.4138774, 17.7106633865,
    22861.5918885581, -5.0102304E-04, -3.7787833E-07, 1.7754362E-09, 2.1863132, 5.5132179088, -9757.6441827375,
    1.2587576E-04, 7.8796768E-08, -3.6937954E-10, 2.1461692, 13.4801375428, 23766.6709819937, 3.0245868E-04,
    5.6971910E-07, -2.7016242E-09, 1.7659832, 11.1677086523, 14809.6776020201, 1.5280981E-04, 3.1869159E-07,
    -1.4608454E-09, -1.6244212, 7.3137297434, 7318.8375983742, -4.3483492E-04, -4.4182525E-07, 2.0841655E-09,
    1.5813036, 5.4387584720, 16552.6081165349, 5.2095955E-04, 7.5618329E-07, -3.5792340E-09, 1.5197528,
    16.7359480324, 40633.6032972747, 1.7441609E-04, 5.5981921E-07, -2.6611908E-09, 1.5156341, 1.7023646816,
    -17876.7861416319, -4.5910508E-04, -6.8233647E-07, 3.2300712E-09, 1.5102092, 5.4977296450, 8399.6847301375,
    -3.3094061E-05, 3.1973462E-08, -1.5436468E-10, -1.3178223, 9.6261586339, 16275.8309783478, -2.8518605E-04,
    -1.9079775E-07, 8.4338673E-10, -1.2642739, 11.9817132061, 24604.5224030729, -1.3287330E-04, 5.9613369E-08,
    -3.4295235E-10, 1.1918723, 22.4217725310, 39518.9747380084, -1.9639754E-04, 1.2294390E-07, -5.9724197E-10,
    1.1346110, 14.4235191419, 31676.6099173011, 2.4767216E-05, 3.0879170E-07, -1.4204120E-09, 1.0857810,
    8.8552797618, 5852.6842220465, 3.1609367E-06, 6.7664088E-08, -2.2006663E-10, -1.0193852, 7.2392703065,
    33629.0898976466, -3.9751134E-05, 2.3556127E-07, -1.1256889E-09, -0.8227141, 11.0814572888,
    16066.2815125171, 1.4748204E-04, 3.1992438E-07, -1.5697249E-09, 0.8042238, 3.5274358950, -33.7870573000,
    2.8263353E-05, 3.7539802E-08, -2.2902113E-10, 0.8025939, 6.7832463846, 16833.1452579809, -9.9779237E-05,
    2.7639907E-08, -1.8858767E-10, -0.7931866, -6.3821400710, -24462.5470518423, -2.4326809E-04,
    -4.9525589E-07, 2.2980217E-09, -0.7910153, 6.3703481443, -591.1013369332, -1.5714346E-04, -1.8089785E-07,
    8.0295327E-10, -0.6674056, 9.1819266386, 24533.5347274576, 5.5197395E-05, 2.7743463E-07, -1.3204870E-09,
    0.6502226, 4.1010449356, -10176.3966721553, -3.0412845E-04, -4.3254175E-07, 2.0981718E-09, -0.6388131,
    6.2958887075, 25719.1509623392, 2.3794032E-04, 4.9648867E-07, -2.4069012E-09 }
local M21 = { 0.0743000, 11.9537467337, 6480.9861772950, 4.9705523E-07, 6.8280480E-08, -2.7450635E-10, 0.0304300,
    8.7259027166, 7737.5900877920, -4.8307078E-06, 6.9513264E-08, -3.8338581E-10, 0.0222900, 12.8540026510,
    15019.2270678508, -2.7985829E-04, -1.9203053E-07, 9.5226618E-10, 0.0199900, 15.2095572232,
    23347.9184925760, -1.2754553E-04, 5.8380585E-08, -2.3407289E-10, 0.0186900, 9.5981921614, -1847.7052474301,
    -1.5181570E-04, -1.8213063E-07, 9.1183272E-10, 0.0169600, 7.1681781524, 16133.8556271171, 9.0955337E-05,
    2.4484477E-07, -1.1116826E-09, 0.0162300, 1.5847795630, 9061.7681128890, -6.6685176E-05, -4.3335556E-09,
    -3.4222998E-11, 0.0141900, -0.7707750092, 733.0766881638, -2.1899793E-04, -2.5474467E-07, 1.1521161E-09 }
local M30 = { 385000.5290396, 1.5707963268, 0.0000000000, 0.0000000E+00, 0.0000000E+00, 0.0000000E+00, -20905.3551378,
    3.9263508990, 8328.6914247251, 1.5231275E-04, 2.5041111E-07, -1.1863391E-09, -3699.1109330, 9.6121753977,
    7214.0628654588, -2.1850087E-04, -1.8646419E-07, 8.7760973E-10, -2955.9675626, 11.9677299699,
    15542.7542901840, -6.6188121E-05, 6.3946925E-08, -3.0872935E-10, -569.9251264, 6.2819054713,
    16657.3828494503, 3.0462550E-04, 5.0082223E-07, -2.3726782E-09, 246.1584797, 7.2566208254,
    -1114.6285592663, -3.7081362E-04, -4.3687530E-07, 2.0639488E-09, -204.5861179, 12.0108556517,
    14914.4523349355, -6.3524240E-05, 6.3330532E-08, -2.5428962E-10, -170.7330791, 14.3232845422,
    23871.4457149091, 8.6124629E-05, 3.1435804E-07, -1.4950684E-09, -152.1378118, 9.6553010794,
    6585.7609102104, -2.1583699E-04, -1.8708058E-07, 9.3204945E-10, -129.6202242, -0.8278839272,
    -7700.3894694766, -1.5497663E-04, -2.4979472E-07, 1.1318993E-09, 108.7427014, 6.7692631483,
    7771.3771450920, -3.3094061E-05, 3.1973462E-08, -1.5436468E-10, 104.7552944, 3.8832252173, 8956.9933799736,
    1.4964887E-04, 2.5102751E-07, -1.2407788E-09, 79.6605685, 0.6705404095, -8538.2408905558, 2.8035534E-04,
    2.6031101E-07, -1.2267725E-09, 48.8883284, 1.5276706450, 628.3019552485, -2.6638815E-06, 6.1639211E-10,
    -5.4439728E-11, -34.7825237, 20.0091090408, 22756.8171556428, -2.8468899E-04, -1.2251727E-07,
    5.6888037E-10, 30.8238599, 11.9246042882, 16171.0562454324, -6.8852003E-05, 6.4563317E-08, -3.6316908E-10,
    24.2084985, 9.5690497159, 7842.3648207073, -2.2116475E-04, -1.8584780E-07, 8.2317000E-10, -23.2104305,
    8.6374600436, 24986.0742741754, 4.5693825E-04, 7.5123334E-07, -3.5590172E-09, -21.6363439, 17.6535544685,
    14428.1257309177, -4.3700174E-04, -3.7292838E-07, 1.7552195E-09, -16.6747239, 6.7261374666,
    8399.6791003405, -3.5757942E-05, 3.2589854E-08, -2.0880440E-10, 14.4026890, 4.9010662531, -9443.3199839914,
    -5.2312637E-04, -6.8728642E-07, 3.2502879E-09, -12.8314035, 14.3664102239, 23243.1437596606, 8.8788511E-05,
    3.1374165E-07, -1.4406287E-09, -11.6499478, 22.3646636130, 31085.5085803679, -1.3237624E-04, 1.2789385E-07,
    -6.1745870E-10, -10.4447578, 16.6788391144, 32200.1371396342, 2.3843738E-04, 5.6476915E-07, -2.6814075E-09,
    10.3211071, 8.7119194804, -1324.1780250970, 6.1854469E-05, 7.3846820E-08, -3.4916281E-10, 10.0562033,
    7.2997465071, -1742.9305145148, -3.6814974E-04, -4.3749170E-07, 2.1183885E-09, -9.8844667, 12.0539813334,
    14286.1503796870, -6.0860358E-05, 6.2714140E-08, -1.9984990E-10, 8.7515625, 6.3563649081, -9652.8694498221,
    -9.0458282E-05, -1.7656429E-07, 8.3717626E-10, -8.3791067, 4.4137085761, -557.3142796331, -1.8540681E-04,
    -2.1843765E-07, 1.0319744E-09, -7.0026961, -3.1834384995, -16029.0808942018, -3.0728938E-04,
    -5.0020584E-07, 2.3182384E-09, 6.3220032, 9.1248177206, 16100.0685698171, 1.1921869E-04, 2.8238458E-07,
    -1.3407038E-09, 5.7508579, 6.2387797896, 17285.6848046987, 3.0196162E-04, 5.0143862E-07, -2.4271179E-09,
    -4.9501349, 9.6984267611, 5957.4589549619, -2.1317311E-04, -1.8769697E-07, 9.8648918E-10, -4.4211770,
    3.0260949818, -209.5494658307, 4.3266809E-04, 5.1072212E-07, -2.4131116E-09, 4.1311145, 11.0674740526,
    7004.5133996281, 2.1416722E-04, 3.2425793E-07, -1.5355019E-09, -3.9579827, 20.0522347225, 22128.5152003943,
    -2.8202511E-04, -1.2313366E-07, 6.2332010E-10, 3.2582371, 14.8106422192, 14985.4400105508, -2.5159493E-04,
    -1.5449073E-07, 7.2324505E-10, -3.1483020, 4.8266068163, 16866.9323152810, -1.2804259E-04, -9.8998954E-09,
    4.0433461E-11, 2.6164092, 14.2801588604, 24499.7476701576, 8.3460748E-05, 3.1497443E-07, -1.5495082E-09,
    2.3536310, 9.5259240342, 8470.6667759558, -2.2382863E-04, -1.8523141E-07, 7.6873027E-10, -2.1171283,
    -0.8710096090, -7072.0875142282, -1.5764051E-04, -2.4917833E-07, 1.0774596E-09, -1.8970368, 17.6966801503,
    13799.8237756692, -4.3433786E-04, -3.7354477E-07, 1.8096592E-09, -1.7385258, 2.0581540038,
    -8886.0057043583, -3.3771956E-04, -4.6884877E-07, 2.2183135E-09, -1.5713944, 22.4077892948,
    30457.2066251194, -1.2971236E-04, 1.2727746E-07, -5.6301898E-10, -1.4225541, 24.7202181853,
    39414.2000050930, 1.9936508E-05, 3.7830496E-07, -1.8037978E-09, -1.4189284, 17.1661967915,
    23314.1314352759, -9.9282182E-05, 9.5920387E-08, -4.6309403E-10, 1.1655364, 3.8400995356, 9585.2953352221,
    1.4698499E-04, 2.5164390E-07, -1.2952185E-09, -1.1169371, 10.9930146158, 33314.7656989005, 6.0925100E-04,
    1.0016445E-06, -4.7453563E-09, 1.0656723, 1.4845449633, 1256.6039104970, -5.3277630E-06, 1.2327842E-09,
    -1.0887946E-10, 1.0586190, 11.9220903668, 8364.7398411275, -2.1850087E-04, -1.8646419E-07, 8.7760973E-10,
    -0.9333176, 9.0816920389, 16728.3705250656, 1.1655481E-04, 2.8300097E-07, -1.3951435E-09, 0.8624328,
    12.4550876470, 6656.7485858257, -4.0390768E-04, -4.0490184E-07, 1.9095841E-09, 0.8512404, 4.3705828944,
    70.9876756153, -1.8807069E-04, -2.1782126E-07, 9.7753467E-10, -0.8488018, 16.7219647962, 31571.8351843857,
    2.4110126E-04, 5.6415276E-07, -2.6269678E-09, -0.7956264, 3.5134526588, -9095.5551701890, 9.4948529E-05,
    4.1873358E-08, -1.9479814E-10 }
local M31 = { 0.5139500, 12.0108556517, 14914.4523349355, -6.3524240E-05, 6.3330532E-08, -2.5428962E-10, 0.3824500,
    9.6553010794, 6585.7609102104, -2.1583699E-04, -1.8708058E-07, 9.3204945E-10, 0.3265400, 3.9694765808,
    7700.3894694766, 1.5497663E-04, 2.4979472E-07, -1.1318993E-09, 0.2639600, 0.7416325637, 8956.9933799736,
    1.4964887E-04, 2.5102751E-07, -1.2407788E-09, 0.1230200, -1.6139220085, 628.3019552485, -2.6638815E-06,
    6.1639211E-10, -5.4439728E-11, 0.0775400, 8.7830116346, 16171.0562454324, -6.8852003E-05, 6.4563317E-08,
    -3.6316908E-10, 0.0606800, 6.4274570623, 7842.3648207073, -2.2116475E-04, -1.8584780E-07, 8.2317000E-10,
    0.0497000, 12.0539813334, 14286.1503796870, -6.0860358E-05, 6.2714140E-08, -1.9984990E-10 }
local M1n = { 3.81034392032, 8.39968473021E+03, -3.31919929753E-05, -- 月球平黄经系数
    3.20170955005E-08, -1.53637455544E-10 }

-- ==================日位置计算===================
local EnnT = 0  -- 调用Enn前先设置EnnT时间变量
function Enn(F) -- 计算E10,E11,E20等,即:某一组周期项或泊松项算出,计算前先设置EnnT时间
    local i
    local v = 0
    for i = 1, #F, 3 do
        v = v + F[i] * math.cos(F[i + 1] + EnnT * F[i + 2])
        -- log.info('Fsize=' .. #F, 'i=' .. i, 'v='..v, 'F[i]='..F[i], 'm='..math.cos(F[i+1]+EnnT*F[i+2]))
    end
    return v
end

function earCal(jd) -- 返回地球位置,日心Date黄道分点坐标
    EnnT = jd / 365250
    -- log.info('EnnT=' .. EnnT)
    local llr = {}
    local t1 = EnnT
    local t2 = t1 * t1
    local t3 = t2 * t1
    local t4 = t3 * t1
    local t5 = t4 * t1
    -- log.info('t1='..t1, 't2='..t2, 't3='..t3, 't4='..t4, 't5='..t5)
    llr[1] = Enn(E10) + Enn(E11) * t1 + Enn(E12) * t2 + Enn(E13) * t3 + Enn(E14) * t4 + Enn(E15) * t5
    -- log.info('sppp')
    llr[2] = Enn(E20) + Enn(E21) * t1
    -- log.info('eppp')
    llr[3] = Enn(E30) + Enn(E31) * t1 + Enn(E32) * t2 + Enn(E33) * t3
    llr[1] = rad2mrad(llr[1])
    -- log.info('llr[0]='..llr[1], 'llr[1]='..llr[2], 'llr[2]='..llr[3])
    return llr
end

function sunCal2(jd) -- 传回jd时刻太阳的地心视黄经及黄纬
    local sun = earCal(jd)
    sun[1] = sun[1] + math.pi
    sun[2] = -sun[2]                  -- 计算太阳真位置
    local d = nutation(jd)
    sun[1] = rad2mrad(sun[1] + d.Lon) -- 补章动
    addGxc(jd, sun)                   -- 补周年黄经光行差
    return sun                        -- 返回太阳视位置
end

-- ==================月位置计算===================
local MnnT = 0  -- 调用Mnn前先设置MnnT时间变量
function Mnn(F) -- 计算M10,M11,M20等,计算前先设置MnnT时间
    local i
    local v = 0
    local t1 = MnnT
    local t2 = t1 * t1
    local t3 = t2 * t1
    local t4 = t3 * t1
    for i = 1, #F, 6 do
        v = v + F[i] * math.sin(F[i + 1] + t1 * F[i + 2] + t2 * F[i + 3] + t3 * F[i + 4] + t4 * F[i + 5])
    end
    return v
end

function moonCal(jd) -- 返回月球位置,返回地心Date黄道坐标
    MnnT = jd / 36525
    local t1 = MnnT
    local t2 = t1 * t1
    local t3 = t2 * t1
    local t4 = t3 * t1
    local llr = {}
    llr[1] = (Mnn(M10) + Mnn(M11) * t1 + Mnn(M12) * t2) / rad
    llr[2] = (Mnn(M20) + Mnn(M21) * t1) / rad
    llr[3] = (Mnn(M30) + Mnn(M31) * t1) * 0.999999949827
    llr[1] = llr[1] + M1n[1] + M1n[2] * t1 + M1n[3] * t2 + M1n[4] * t3 + M1n[5] * t4
    llr[1] = rad2mrad(llr[1]) -- 地心Date黄道原点坐标(不含岁差)
    addPrece(jd, llr)         -- 补岁差
    return llr
end

function moonCal2(jd) -- 传回月球的地心视黄经及视黄纬
    local moon = moonCal(jd)
    local d = nutation(jd)
    moon[1] = rad2mrad(moon[1] + d.Lon) -- 补章动
    return moon
end

function moonCal3(jd) -- 传回月球的地心视赤经及视赤纬
    local moon = moonCal(jd)
    HCconv(moon, hcjj1(jd))
    nutationRaDec(jd, moon) -- 补赤经及赤纬章动
    -- 如果黄赤转换前补了黄经章动及交章动,就不能再补赤经赤纬章动
    return moon
end

-- ==================地心坐标中的日月位置计算===================
function jiaoCai(lx, t, jiao)
    -- lx=1时计算t时刻日月角距与jiao的差, lx=0计算t时刻太阳黄经与jiao的差
    local sun = earCal(t) -- 计算太阳真位置(先算出日心坐标中地球的位置)
    sun[1] = sun[1] + math.pi
    sun[2] = -sun[2]      -- 转为地心坐标
    addGxc(t, sun)        -- 补周年光行差
    -- log.info('sun[1]=' .. sun[1], 'sun[2]=' .. sun[2])
    if lx == 0 then
        local d = nutation(t)
        sun[1] = sun[1] + d.Lon -- 补黄经章动
        return rad2mrad(jiao - sun[1])
    end
    local moon = moonCal(t) -- 日月角差与章动无关
    return rad2mrad(jiao - (moon[1] - sun[1]))
end

-- ==================已知位置反求时间===================
function jiaoCal(t1, jiao, lx) -- t1是J2000起算儒略日数
    -- 已知角度(jiao)求时间(t)
    -- lx=0是太阳黄经达某角度的时刻计算(用于节气计算)
    -- lx=1是日月角距达某角度的时刻计算(用于定朔望等)
    -- 传入的t1是指定角度对应真时刻t的前一些天
    -- 对于节气计算,应满足t在t1到t1+360天之间,对于Y年第n个节气(n=0是春分),t1可取值Y*365.2422+n*15.2
    -- 对于朔望计算,应满足t在t1到t1+25天之间,在此范围之外,求右边的根
    local t2 = t1
    local t = 0
    local v
    if lx == 0 then
        t2 = t2 + 360 -- 在t1到t2范围内求解(范气360天范围),结果置于t
    else
        t2 = t2 + 25
    end
    jiao = jiao * math.pi / 180 -- 待搜索目标角
    -- 利用截弦法计算
    -- log.info('lx=' .. lx .. ', t1=' .. t1 .. ', t2=' .. t2 .. ', jiao=' .. jiao)
    local v1 = jiaoCai(lx, t1, jiao) -- v1,v2为t1,t2时对应的黄经
    local v2 = jiaoCai(lx, t2, jiao)
    -- log.info('v1=' .. v1 .. ', v2=' ..v2)
    if v1 < v2 then
        v2 = v2 - 2 * math.pi
    end                            -- 减2pi作用是将周期性角度转为连续角度
    local k = 1, k2, i             -- k是截弦的斜率
    for i = 1, 10 do               -- 快速截弦求根,通常截弦三四次就已达所需精度
        k2 = (v2 - v1) / (t2 - t1) -- 算出斜率
        if math.abs(k2) > 1e-15 then
            k = k2
        end                      -- 差商可能为零,应排除
        t = t1 - v1 / k
        v = jiaoCai(lx, t, jiao) -- 直线逼近法求根(直线方程的根)
        if v > 1 then
            v = v - 2 * math.pi
        end -- 一次逼近后,v1就已接近0,如果很大,则应减1周
        if math.abs(v) < 1e-8 then
            break
        end -- 已达精度
        t1 = t2
        v1 = v2
        t2 = t
        v2 = v -- 下一次截弦
    end
    return t
end

-- ==================节气计算===================
local jqB = { -- 节气表
    "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露",
    "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至", "小寒", "大寒", "立春", "雨水", "惊蛰" }

function JQtest(y) -- 节气使计算范例,y是年分,这是个测试函数
    local i, q, s1, s2
    y = tostring(y)
    local jd = 365.2422 * (tonumber(y.sub(y, 1, 4)) - 2000)
    for i = 0, 23 do
        q = jiaoCal(jd + i * 15.2, i * 15, 0) + J2000 + 8 / 24 -- 计算第i个节气(i=0是春分),结果转为北京时
        -- log.info('q=' .. q)
        JDate:setFromJD(q, 1)
        s1 = JDate:toStr() -- 将儒略日转成世界时
        JDate:setFromJD(q, 0)
        s2 = JDate:toStr() -- 将儒略日转成日期格式(输出日期形式的力学时)
        jqData = s1.sub(s1.gsub(s1, "^( )", ""), 1, 10)
        jqData = jqData.gsub(jqData, "-", "")
        -- log.info(jqB[i+1] .. " : " .. jqData .. " " .. jqData.len(jqData) ) --显示
        if (jqData == y) then
            return "-" .. jqB[i + 1]
        end
    end
    return ""
end

function GetNextJQ(y) -- 节气使计算范例,y是年分,这是个测试函数
    local i, obj, q, s1, s2
    y = tostring(y)
    local jd = 365.2422 * (tonumber(y.sub(y, 1, 4)) - 2000)
    obj = {}
    for i = 0, 23 do
        q = jiaoCal(jd + i * 15.2, i * 15, 0) + J2000 + 8 / 24 -- 计算第i个节气(i=0是春风),结果转为北京时
        -- log.info('q=' .. q)
        JDate:setFromJD(q, 1)
        s1 = JDate:toStr() -- 将儒略日转成世界时
        JDate:setFromJD(q, 0)
        s2 = JDate:toStr() -- 将儒略日转成日期格式(输出日期形式的力学时)
        jqData = s1.sub(s1.gsub(s1, "^( )", ""), 1, 10)
        jqData = jqData.gsub(jqData, "-", "")
        if (jqData >= y) then
            table.insert(obj, jqB[i + 1] .. " " .. s1.sub(s1.gsub(s1, "^( )", ""), 1, 10))
            -- log.info(i .. s1.sub(s1.gsub(s1, "^( )", ""),1,10))
        end
    end
    return obj
end

function getJQ(y) -- 返回一年中各个节气的时间表，从春分开始
    local i
    local jd = 365.2422 * (y - 2000)
    local q
    local jq = {}
    for i = 0, 23 do
        q = jiaoCal(jd + i * 15.2, i * 15, 0) + J2000 + 8 / 24 -- 计算第i个节气(i=0是春分),结果转为北京时
        JDate:setFromJD(q, 1)
        jq[i + 1] = JDate:JQ()                                 -- 将儒略日转成世界时
    end
    return jq
end

-- 返回一年的二十四个节气,从立春开始
function getYearJQ(y)
    local jq1 = getJQ(y - 1) -- 上一年
    local jq2 = getJQ(y)     -- 当年
    local jq = {}
    for i = 1, 3 do
        jq[i] = jq1[i + 21]
    end
    for i = 1, 21 do
        jq[i + 3] = jq2[i]
    end
    return jq
end

-- =================定朔弦望计算========================
function dingSuo(y, arc) -- 这是个测试函数
    local i, jd = 365.2422 * (y - 2000), q, s1, s2
    log.info("月份:世界时  原子时<br>")
    for i = 0, 11 do
        q = jiaoCal(jd + 29.5 * i, arc, 1) + J2000 + 8 / 24 -- 计算第i个节气(i=0是春风),结果转为北京时
        JDate.setFromJD(q, 1)
        s1 = JDate:toStr() -- 将儒略日转成世界时
        JDate.setFromJD(q, 0)
        s2 = JDate:toStr() -- 将儒略日转成日期格式(输出日期形式的力学时)
        log.info((i + 1) .. "月 : " .. s1 .. " " .. s2) -- 显示
    end
end

-- =================农历计算========================
--[[*****
1.冬至所在的UTC日期保存在A[0],根据"规定1"得知在A[0]之前(含A[0])的那个UTC朔日定为年首日期
冬至之后的中气分保存在A[1],A[2],A[3]...A[13],其中A[12]又回到了冬至,共计算13次中气
2.连续计算冬至后14个朔日,即起算时间时A[0]+1
14个朔日编号为0,1...12,保存在C[0],C[1]...C[13]
这14个朔日表示编号为0月,1月,...12月0月的各月终止日期,但要注意实际终止日是新月初一,不属本月
这14个朔日同样表示编号为1月,2月...的开始日期
设某月编号为n,那么开始日期为C[n-1],结束日期为C[n],如果每月都含中气,该月所含的中气为A[n]
注:为了全总计算出13个月的大小月情况,须算出14个朔日。
3.闰年判断:含有13个月的年份是闰年
当第13月(月编号12月)终止日期大于冬至日,  即C[12]〉A[12], 那么该月是新年,本年没月12月,本年共12个月
当第13月(月编号12月)终止日期小等于冬至日,即C[12]≤A[12],那么该月是本年的有效月份,本年共13个月
4.闰年中处理闰月:
13个月中至少1个月份无中气,首个无中气的月置闰,在n=1...12月中找到闰月,即C[n]≤A[n]
从农历年首的定义知道,0月一定含有中气冬至,所以不可能是闰月。
首月有时很贪心,除冬至外还可能再吃掉本年或前年的另一个中气
定出闰月后,该月及以后的月编号减1
5.以上所述的月编号不是日常生活中说的"正月","二月"等月名称:
如果"建子",0月为首月,如果"建寅",2月的月名"正月",3月是"二月",其余类推
*****--]]

-- local yueMing={"正","二","三","四","五","六","七","八","九","十","冬","腊"}
--
-- function paiYue(inYear) --农历排月序计算,可定出农历
--  --y=in1.value-0
--  local y = inYear-0
--  local zq={},jq={}, hs={}  --中气表,节气表,日月合朔表
--
--  --从冬至开始,连续计算14个中气时刻
--  local i,t1=365.2422*(y-2000)-50 --农历年首始于前一年的冬至,为了节气中气一起算,取前年大雪之前
--  for i=0,13 do   --计算节气(从冬至开始),注意:返回的是力学时
--    zq[i+1]=jiaoCal(t1+i*30.4,i*30-90, 0) --中气计算,冬至的太阳黄经是270度(或-90度)
--    jq[i+1]=jiaoCal(t1+i*30.4,i*30-105,0) --顺便计算节气,它不是农历定朔计算所必需的
-- end
-- ...
-- end

function GetNowTimeJq(date)
    local JQtable1, JQtable2
    date = tostring(date)
    if string.len(date) < 8 then
        return "无效日期"
    end
    JQtable2 = GetNextJQ(date)
    if tonumber(string.sub(date, 5, 8)) < 322 then
        JQtable1 = GetNextJQ(tonumber(string.sub(date, 1, 4)) - 1 .. string.sub(date, 5, 8))
        -- log.info(#JQtable1)
        if tonumber(string.sub(date, 5, 8)) < 108 then
            for i = 20, 24 do
                table.insert(JQtable2, i - 19, JQtable1[i])
            end
        elseif tonumber(string.sub(date, 5, 8)) < 122 then
            for i = 21, 24 do
                table.insert(JQtable2, i - 20, JQtable1[i])
            end
        elseif tonumber(string.sub(date, 5, 8)) < 206 then
            for i = 22, 24 do
                table.insert(JQtable2, i - 21, JQtable1[i])
            end
        elseif tonumber(string.sub(date, 5, 8)) < 221 then
            for i = 23, 24 do
                table.insert(JQtable2, i - 22, JQtable1[i])
            end
        else
            table.insert(JQtable2, 1, JQtable1[24])
        end
        -- log.info(table.concat(JQtable2))
    end
    return JQtable2
end

-- 公历转干支历实现
--[[干支历的年以立春发生时刻（注意，不是立春日的0时）为年干支的起点；各月干支以十二节时刻（注意，不一定是各节气日的0时）
--]]
GanZhiLi = {}

-- 创建干支历对象
function GanZhiLi:new()
    local o = {}
    setmetatable(o, self)
    self.__index = self
    o:setTime(os.time())
    return o
end

-- 将offset的数值转化为特定偏移下的周期数，起始数，偏移量，周期
function GanZhiLi:calRound(start, offset, round)
    if start > round or start <= 0 then
        return nil
    end -- 参数不对
    offset = math.floor(math.fmod(start + offset, round))
    if offset >= 0 then
        if offset == 0 then
            offset = round
        end
        return offset
    else
        return round + offset
    end
end

-- 周期循环数
function calR2(n, round)
    local x = math.floor(math.fmod(n, round))
    if x == 0 then
        x = round
    end
    return x
end

-- 设置用于转换干支历的公历时间
function GanZhiLi:setTime(t)
    self.ttime = t
    self.tday = os.date('*t', t)
    -- for k,v in pairs(self.tday) do
    --    log.info(k,v)
    -- end
    -- 先取公历今年的干支
    self.jqs = getYearJQ(self.tday.year)
    self.ganZhiYearNum = self:calGanZhiYearNum()
    if self.ganZhiYearNum ~= self.tday.year then
        -- 如果在节气上还没到今年的立春，则还没到干支历的今年，需要取干支历的年份的24节气
        self.jqs = getYearJQ(self.ganZhiYearNum)
    end
    self.ganZhiMonNum = self:calGanZhiMonthNum()
    self.curJq = self:getCurJQ()
end

function GanZhiLi:getCurJQ()
    -- for i=1,24 do
    --    local x = os.date('*t', self.jqs[i])
    --    log.info(x.year, x.month, x.day, x.hour, x.min, x.sec)
    -- end
    local x = 0
    if self.ttime < self.jqs[1] then
        return nil
    end -- 出错，计算错年了？
    for i = 1, 23 do
        if self.jqs[i] <= self.ttime and self.jqs[i + 1] > self.ttime then
            x = i
            break
        end
    end
    if x == 0 then
        x = 24
    end
    return x -- 返回以立春为起始序号1的节气
end

-- 根据公历年份和节气计算干支历的年份
function GanZhiLi:calGanZhiYearNum()
    if (self.ttime < self.jqs[1]) then
        return self.tday.year - 1
    else
        return self.tday.year
    end
end

-- 获取干支月份
function GanZhiLi:calGanZhiMonthNum()
    if self.ttime < self.jqs[1] then
        return nil
    end
    local x = 0
    if self.ttime < self.jqs[1] then
        return nil
    end -- 出错，计算错年了？
    for i = 1, 23 do
        if self.jqs[i] <= self.ttime and self.jqs[i + 1] > self.ttime then
            x = i
        end
    end
    if x == 0 then
        x = 24
    end
    return math.floor((x + 1) / 2)
end

-- 返回年的干支序号，1为甲子。。。
function GanZhiLi:getYearGanZhi()
    local jiaziYear = 1984 -- 甲子年
    -- log.info(self.ganZhiYearNum)
    local yeardiff = self.ganZhiYearNum - jiaziYear
    return self:calRound(1, yeardiff, 60)
end

-- 返回年的天干号，1为甲
function GanZhiLi:getYearGan()
    local idx = self:getYearGanZhi()
    return self:calR2(idx, 10)
end

-- 返回年的地支号，1为子
function GanZhiLi:getYearZhi()
    local idx = self:getYearGanZhi()
    return self:calR2(idx, 12)
end

-- 返回月的干支号
function GanZhiLi:getMonGanZhi()
    local ck = {
        year = 2010,
        month = 2,
        day = 4,
        hour = 6,
        min = 42,
        sec = 0
    }
    local x = os.time(ck) -- 参考月，立春时间2010-2-4 6:42:00对应的干支序号为15
    local ydiff = self.ganZhiYearNum - ck.year
    local mdiff = self.ganZhiMonNum - 1
    if ydiff >= 0 then
        mdiff = ydiff * 12 + mdiff
    else
        mdiff = (ydiff + 1) * 12 + mdiff - 12
    end
    return self:calRound(15, mdiff, 60)
end

function GanZhiLi:getMonGan()
    local idx = self:getMonGanZhi()
    return self:calR2(idx, 10)
end

function GanZhiLi:getMonZhi()
    local idx = self:getMonGanZhi()
    return self:calR2(idx, 12)
end

-- 返回日的干支号，甲子从1开始
function GanZhiLi:getDayGanZhi()
    local DAYSEC = 24 * 3600
    local jiaziDayTime = os.time({
        year = 2012,
        month = 8,
        day = 30,
        hour = 23,
        min = 0,
        sec = 0
    })
    local daydiff = math.floor((self.ttime - jiaziDayTime) / DAYSEC)
    return self:calRound(1, daydiff, 60)
end

-- 返回日的天干号
function GanZhiLi:getDayGan()
    local idx = self:getDayGanZhi()
    return self:calR2(idx, 10)
end

-- 返回日的地支号
function GanZhiLi:getDayZhi()
    local idx = self:getDayGanZhi()
    return self:calR2(idx, 12)
end

-- 返回时辰的干支号
function GanZhiLi:getHourGanZhi()
    local SHICHENSEC = 3600 * 2
    local jiaziShiTime = os.time({
        year = 2012,
        month = 8,
        day = 30,
        hour = 23,
        min = 0,
        sec = 0
    })
    local shiDiff = math.floor((self.ttime - jiaziShiTime) / SHICHENSEC)
    return self:calRound(1, shiDiff, 60)
end

-- 返回时干号
function GanZhiLi:getShiGan()
    local idx = self:getHourGanZhi()
    return self:calR2(idx, 10)
end

-- 返回时支号
function GanZhiLi:getShiZhi()
    local idx = self:getHourGanZhi()
    return self:calR2(idx, 12)
end

-- ====================以下是测试代码=============

local jqB = { -- 节气表
    "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑",
    "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至", "小寒", "大寒" }
-- 天干
local tiangan = { '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸' }

-- 地支
local dizhi = { '子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥' }

-- 根据六十甲子序号，返回六十甲子字符串,甲子从1开始
local function get60JiaZiStr(i)
    local gan = i % 10
    if gan == 0 then
        gan = 10
    end
    local zhi = i % 12
    if zhi == 0 then
        zhi = 12
    end
    return tiangan[gan] .. dizhi[zhi]
end

function lunarJzl(y)
    local x, yidx, midx, didx, hidx
    y = tostring(y)
    x = GanZhiLi:new()
    x:setTime(os.time({
        year = tonumber(y.sub(y, 1, 4)),
        month = tonumber(y.sub(y, 5, -5)),
        day = tonumber(y.sub(y, 7, -3)),
        hour = tonumber(y.sub(y, 9, -1)),
        min = 4,
        sec = 5
    }))
    yidx = x:getYearGanZhi()
    midx = x:getMonGanZhi()
    didx = x:getDayGanZhi()
    hidx = x:getHourGanZhi()
    GzData = get60JiaZiStr(yidx) .. '年' .. get60JiaZiStr(midx) .. '月' .. get60JiaZiStr(didx) .. '日' ..
        get60JiaZiStr(hidx) .. '时'
    -- log.info('干支:'  .. GzData)
    return GzData
end

local function time_to_num(time)
    pattern = "(%d+):(%d+) +([AP]M)"
    if string.match(time, pattern) ~= nil then
        hours, minutes, am = string.match(time, pattern)
        if ((am == "AM") and (tonumber(hours) >= 12)) then
            hours = hours - 12
        elseif ((am == "PM") and (tonumber(hours) < 12)) then
            hours = hours + 12
        end
    else
        pattern = "(%d+):(%d+)"
        hours, minutes = string.match(time, pattern)
    end
    return (hours * 60) + minutes
end

local GetLunarSichen = function(time, t)
    local time = tonumber(time)
    local LunarSichen = { "子时(夜半｜三更)", "丑时(鸡鸣｜四更)", "寅时(平旦｜五更)",
        "卯时(日出)", "辰时(食时)", "巳时(隅中)", "午时(日中)", "未时(日昳)",
        "申时(晡时)", "酉时(日入)", "戌时(黄昏｜一更)", "亥时(人定｜二更)" }
    if tonumber(t) == 1 then
        sj = math.floor((time + 1) / 2) + 1
    elseif tonumber(t) == 0 then
        sj = math.floor((time + 13) / 2) + 1
    end
    if sj > 12 then
        return LunarSichen[sj - 12]
    else
        return LunarSichen[sj]
    end
end

-- 十进制转二进制
function Dec2bin(n)
    local t, t1, t2
    local tables = { "" }
    t = tonumber(n)
    while math.floor(t / 2) >= 1 do
        t1 = math.fmod(t, 2)
        if t1 > 0 then
            if #tables > 0 then
                table.insert(tables, 1, 1)
            else
                tables[1] = 1
            end
        else
            if #tables > 0 then
                table.insert(tables, 1, 0)
            else
                tables[1] = 0
            end
        end
        t = math.floor(t / 2)
        if t == 1 then
            if #tables > 0 then
                table.insert(tables, 1, 1)
            else
                tables[1] = 1
            end
        end
    end
    return string.gsub(table.concat(tables), "^[0]+", "")
end

-- 2/10/16进制互转
local function system(x, inPuttype, outputtype)
    local r
    if (tonumber(inPuttype) == 2) then
        if (tonumber(outputtype) == 10) then     -- 2进制-->10进制
            r = tonumber(tostring(x), 2)
        elseif (tonumber(outputtype) == 16) then -- 2进制-->16进制
            r = bin2hex(tostring(x))
        end
    elseif (tonumber(inPuttype) == 10) then
        if (tonumber(outputtype) == 2) then      -- 10进制-->2进制
            r = Dec2bin(tonumber(x))
        elseif (tonumber(outputtype) == 16) then -- 10进制-->16进制
            r = string.format("%x", x)
        end
    elseif (tonumber(inPuttype) == 16) then
        if (tonumber(outputtype) == 2) then      -- 16进制-->2进制
            r = Dec2bin(tonumber(tostring(x), 16))
        elseif (tonumber(outputtype) == 10) then -- 16进制-->10进制
            r = tonumber(tostring(x), 16)
        end
    end
    return r
end

-- 农历16进制数据分解
local function Analyze(Data)
    local rtn1, rtn2, rtn3, rtn4
    rtn1 = system(string.sub(Data, 1, 3), 16, 2)
    while string.len(rtn1) < 12 do
        rtn1 = "0" .. rtn1
    end
    rtn2 = string.sub(Data, 4, 4)
    rtn3 = system(string.sub(Data, 5, 5), 16, 10)
    rtn4 = system(string.sub(Data, -2, -1), 16, 10)
    if string.len(rtn4) == 3 then
        rtn4 = "0" .. system(string.sub(Data, -2, -1), 16, 10)
    end
    -- string.gsub(rtn1, "^[0]*", "")
    return { rtn1, rtn2, rtn3, rtn4 }
end

-- 年天数判断
local function IsLeap(y)
    local year = tonumber(y)
    if math.fmod(year, 400) ~= 0 and math.fmod(year, 4) == 0 or math.fmod(year, 400) == 0 then
        return 366
    else
        return 365
    end
end

-- 计算日期差，两个8位数日期之间相隔的天数，date2>date1
function diffDate(date1, date2)
    local t1, t2, n, total
    total = 0
    date1 = tostring(date1)
    date2 = tostring(date2)
    if tonumber(date2) > tonumber(date1) then
        n = tonumber(string.sub(date2, 1, 4)) - tonumber(string.sub(date1, 1, 4))
        if n > 1 then
            for i = 1, n - 1 do
                total = total + IsLeap(tonumber(string.sub(date1, 1, 4)) + i)
            end
            total = total + leaveDate(tonumber(string.sub(date2, 1, 8))) + IsLeap(tonumber(string.sub(date1, 1, 4))) -
                leaveDate(tonumber(string.sub(date1, 1, 8)))
        elseif n == 1 then
            total = IsLeap(tonumber(string.sub(date1, 1, 4))) - leaveDate(tonumber(string.sub(date1, 1, 8))) +
                leaveDate(tonumber(string.sub(date2, 1, 8)))
        else
            total = leaveDate(tonumber(string.sub(date2, 1, 8))) - leaveDate(tonumber(string.sub(date1, 1, 8)))
            -- log.info(date1 .. "-" .. date2)
        end
    elseif tonumber(date2) == tonumber(date1) then
        return 0
    else
        return -1
    end
    return total
end

-- 公历倒计时(每年)
local function diffDate2(date1, date2)
    while diffDate(date1, date2) == -1 do
        date2 = tointeger(date2 + 1000000)
    end
    result = diffDate(date1, date2)
    return result
end
-- 公历倒计时结束

-- 返回当年过了多少天
function leaveDate(y)
    local day, total
    total = 0
    if IsLeap(tonumber(string.sub(y, 1, 4))) > 365 then
        day = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    else
        day = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    end
    if tonumber(string.sub(y, 5, 6)) > 1 then
        for i = 1, tonumber(string.sub(y, 5, 6)) - 1 do
            total = total + day[i]
        end
        total = total + tonumber(string.sub(y, 7, 8))
    else
        return tonumber(string.sub(y, 7, 8))
    end
    return tonumber(total)
end

-- 公历转农历，支持转化范围公元1900-2100年
-- 公历日期 Gregorian:格式 YYYYMMDD
-- <返回值>农历日期 中文 天干地支属相
function Date2LunarDate(Gregorian)
    -- 天干名称
    local cTianGan = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" }
    -- 地支名称
    local cDiZhi = { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" }
    -- 属相名称
    local cShuXiang = { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" }
    -- 农历日期名
    local cDayName = { "初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九",
        "初十", "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八",
        "十九", "二十", "廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七",
        "廿八", "廿九", "三十" }
    -- 农历月份名
    local cMonName = { "正月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月",
        "十月", "冬月", "腊月" }

    -- 农历数据
    local wNongliData = { "AB500D2", "4BD0883", "4AE00DB", "A5700D0", "54D0581", "D2600D8", "D9500CC", "655147D",
        "56A00D5", "9AD00CA", "55D027A", "4AE00D2", "A5B0682", "A4D00DA", "D2500CE", "D25157E",
        "B5400D6", "D6A00CB", "ADA027B", "95B00D3", "49717C9", "49700DC", "A4B00D0", "B4B0580",
        "6A500D8", "6D400CD", "AB5147C", "2B600D5", "95700CA", "52F027B", "49700D2", "6560682",
        "D4A00D9", "EA500CE", "6A9157E", "5AD00D6", "2B600CC", "86E137C", "92E00D3", "C8D1783",
        "C9500DB", "D4A00D0", "D8A167F", "B5500D7", "56A00CD", "A5B147D", "25D00D5", "92D00CA",
        "D2B027A", "A9500D2", "B550781", "6CA00D9", "B5500CE", "535157F", "4DA00D6", "A5B00CB",
        "457137C", "52B00D4", "A9A0883", "E9500DA", "6AA00D0", "AEA0680", "AB500D7", "4B600CD",
        "AAE047D", "A5700D5", "52600CA", "F260379", "D9500D1", "5B50782", "56A00D9", "96D00CE",
        "4DD057F", "4AD00D7", "A4D00CB", "D4D047B", "D2500D3", "D550883", "B5400DA", "B6A00CF",
        "95A1680", "95B00D8", "49B00CD", "A97047D", "A4B00D5", "B270ACA", "6A500DC", "6D400D1",
        "AF40681", "AB600D9", "95700CE", "4AF057F", "49700D7", "64B00CC", "74A037B", "EA500D2",
        "6B50883", "5AC00DB", "AB600CF", "96D0580", "92E00D8", "C9600CD", "D95047C", "D4A00D4",
        "DA500C9", "755027A", "56A00D1", "ABB0781", "25D00DA", "92D00CF", "CAB057E", "A9500D6",
        "B4A00CB", "BAA047B", "AD500D2", "55D0983", "4BA00DB", "A5B00D0", "5171680", "52B00D8",
        "A9300CD", "795047D", "6AA00D4", "AD500C9", "5B5027A", "4B600D2", "A6E0681", "A4E00D9",
        "D2600CE", "EA6057E", "D5300D5", "5AA00CB", "76A037B", "96D00D3", "4AF0B83", "4AD00DB",
        "A4D00D0", "D0B1680", "D2500D7", "D5200CC", "DD4057C", "B5A00D4", "56D00C9", "55B027A",
        "49B00D2", "A570782", "A4B00D9", "AA500CE", "B25157E", "6D200D6", "ADA00CA", "4B6137B",
        "93700D3", "49F08C9", "49700DB", "64B00D0", "68A1680", "EA500D7", "6AA00CC", "A6C147C",
        "AAE00D4", "92E00CA", "D2E0379", "C9600D1", "D550781", "D4A00D9", "DA500CD", "5D5057E",
        "56A00D6", "A6D00CB", "55D047B", "52D00D3", "A9B0883", "A9500DB", "B4A00CF", "B6A067F",
        "AD500D7", "55A00CD", "ABA047C", "A5B00D4", "52B00CA", "B27037A", "69300D1", "7330781",
        "6AA00D9", "AD500CE", "4B5157E", "4B600D6", "A5700CB", "54E047C", "D1600D2", "E960882",
        "D5200DA", "DAA00CF", "6AA167F", "56D00D7", "4AE00CD", "A9D047D", "A2D00D4", "D1500C9",
        "F250279", "D5200D1", "DB20781", "B5A00D9", "55D00CF", "4DB0580", "49B00D7", "A4B00CC",
        "D4B047C", "AA500D4", "B550983", "6D200DB", "AD600D0", "5760681", "93700D8" }
    Gregorian = tostring(Gregorian)
    local Year, Month, Day, Pos, Data0, Data1, MonthInfo, LeapInfo, Leap, Newyear, Data2, Data3, LYear, thisMonthInfo
    Year = tonumber(Gregorian.sub(Gregorian, 1, 4))
    Month = tonumber(Gregorian.sub(Gregorian, 5, 6))
    Day = tonumber(Gregorian.sub(Gregorian, 7, 8))
    if (Year > 2100 or Year < 1899 or Month > 12 or Month < 1 or Day < 1 or Day > 31 or string.len(Gregorian) < 8) then
        return "无效日期"
    end
    -- log.info(Year .. "-" .. Month .. "-" .. Day)
    -- 获取两百年内的农历数据
    Pos = Year - 1900 + 2
    Data0 = wNongliData[Pos - 1]
    Data1 = wNongliData[Pos]
    -- 判断农历年份
    local tb1 = Analyze(Data1)
    MonthInfo = tb1[1]
    LeapInfo = tb1[2]
    Leap = tb1[3]
    Newyear = tb1[4]
    Date1 = Year .. Newyear
    Date2 = Gregorian
    Date3 = diffDate(Date1, Date2) -- 和当年农历新年相差的天数
    -- log.info(Date3 .. "-11")
    if (Date3 < 0) then
        -- log.info(Data0 .. "-2")
        tb1 = Analyze(Data0)
        Year = Year - 1
        MonthInfo = tb1[1]
        LeapInfo = tb1[2]
        Leap = tb1[3]
        Newyear = tb1[4]
        Date1 = Year .. Newyear
        Date2 = Gregorian
        Date3 = diffDate(Date1, Date2)
        -- log.info(Date2 .. "--" .. Date1 .. "--" .. Date3)
    end
    -- log.info(MonthInfo .. "-" .. LeapInfo .. "-" .. Leap .. "-" .. Newyear .. "-" .. Year)
    Date3 = Date3 + 1
    LYear = Year     -- 农历年份，就是上面计算后的值
    if Leap > 0 then -- 有闰月
        thisMonthInfo = string.sub(MonthInfo, 1, Leap) .. LeapInfo .. string.sub(MonthInfo, Leap + 1)
    else
        thisMonthInfo = MonthInfo
    end
    local thisMonth, thisDays, LDay, Isleap, LunarYear, LunarMonth
    for i = 1, 13 do
        thisMonth = string.sub(thisMonthInfo, i, i)
        thisDays = 29 + thisMonth
        if (Date3 > thisDays) then
            Date3 = Date3 - thisDays
        else
            if (Leap > 0) then
                if (Leap >= i) then
                    LMonth = i
                    Isleap = 0
                else
                    LMonth = i - 1
                    if i - Leap == 1 then
                        Isleap = 1
                    else
                        Isleap = 0
                    end
                end
            else
                LMonth = i
                Isleap = 0
            end
            LDay = math.floor(Date3)
            break
        end
    end
    -- log.info(LYear .. "-" .. LMonth .. "-" .. LDay)
    if Isleap > 0 then
        LunarMonth = "闰" .. cMonName[LMonth]
    else
        LunarMonth = cMonName[LMonth]
    end
    -- log.info(LDay)
    LunarYear = cTianGan[math.fmod(LYear - 4, 10) + 1] .. cDiZhi[math.fmod(LYear - 4, 12) + 1] .. "年(" ..
        cShuXiang[math.fmod(LYear - 4, 12) + 1] .. ")" .. LunarMonth .. cDayName[LDay]
    -- log.info(LunarYear)
    return LunarYear
end

-- Date日期参数格式YYMMDD，dayCount累加的天数--修复了可能为6月00日的可能性,回退到5月31日
-- 返回值：公历日期
local function GettotalDay(Date, dayCount)
    local Year, Month, Day, days, total, t
    Date = tostring(Date)
    Year = tonumber(Date.sub(Date, 1, 4))
    Month = tonumber(Date.sub(Date, 5, 6))
    Day = tonumber(Date.sub(Date, 7, 8))

    -- 根据是否是闰年设置天数表
    if IsLeap(Year) > 365 then
        days = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    else
        days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    end

    -- 判断天数是否超过当前月份的剩余天数
    if dayCount > days[Month] - Day then
        total = dayCount - (days[Month] - Day) -- 减去当前月份剩余的天数
        Month = Month + 1                      -- 移动到下个月
        if Month > 12 then
            Month = 1                          -- 如果超过12月，跳转到1月
            Year = Year + 1                    -- 增加一年
        end

        -- 继续加上余下的天数，跨月处理
        while total > days[Month] do
            total = total - days[Month] -- 减去当前月份的天数
            Month = Month + 1           -- 移动到下个月
            if Month > 12 then
                Month = 1               -- 如果超过12月，跳转到1月
                Year = Year + 1         -- 增加一年
            end
        end
    else
        total = Day + dayCount -- 如果不跨月，直接累加
    end

    -- 确保月份和日期都是两位数格式
    if string.len(Month) == 1 then
        Month = "0" .. Month
    end
    if string.len(total) == 1 then
        total = "0" .. total
    end

    -- 返回格式化的日期
    return Year .. "年" .. Month .. "月" .. total .. "日"
end

-- 农历转公历
-- 农历 Gregorian:数字格式 YYYYMMDD
-- <返回值>公历日期 格式YYYY年MM月DD日
-- 农历日期月份为闰月需指定参数IsLeap为1，非闰月需指定参数IsLeap为0
function LunarDate2Date(Gregorian, IsLeap)
    LunarData = { "AB500D2", "4BD0883", "4AE00DB", "A5700D0", "54D0581", "D2600D8", "D9500CC", "655147D", "56A00D5",
        "9AD00CA", "55D027A", "4AE00D2", "A5B0682", "A4D00DA", "D2500CE", "D25157E", "B5400D6", "D6A00CB",
        "ADA027B", "95B00D3", "49717C9", "49700DC", "A4B00D0", "B4B0580", "6A500D8", "6D400CD", "AB5147C",
        "2B600D5", "95700CA", "52F027B", "49700D2", "6560682", "D4A00D9", "EA500CE", "6A9157E", "5AD00D6",
        "2B600CC", "86E137C", "92E00D3", "C8D1783", "C9500DB", "D4A00D0", "D8A167F", "B5500D7", "56A00CD",
        "A5B147D", "25D00D5", "92D00CA", "D2B027A", "A9500D2", "B550781", "6CA00D9", "B5500CE", "535157F",
        "4DA00D6", "A5B00CB", "457137C", "52B00D4", "A9A0883", "E9500DA", "6AA00D0", "AEA0680", "AB500D7",
        "4B600CD", "AAE047D", "A5700D5", "52600CA", "F260379", "D9500D1", "5B50782", "56A00D9", "96D00CE",
        "4DD057F", "4AD00D7", "A4D00CB", "D4D047B", "D2500D3", "D550883", "B5400DA", "B6A00CF", "95A1680",
        "95B00D8", "49B00CD", "A97047D", "A4B00D5", "B270ACA", "6A500DC", "6D400D1", "AF40681", "AB600D9",
        "95700CE", "4AF057F", "49700D7", "64B00CC", "74A037B", "EA500D2", "6B50883", "5AC00DB", "AB600CF",
        "96D0580", "92E00D8", "C9600CD", "D95047C", "D4A00D4", "DA500C9", "755027A", "56A00D1", "ABB0781",
        "25D00DA", "92D00CF", "CAB057E", "A9500D6", "B4A00CB", "BAA047B", "AD500D2", "55D0983", "4BA00DB",
        "A5B00D0", "5171680", "52B00D8", "A9300CD", "795047D", "6AA00D4", "AD500C9", "5B5027A", "4B600D2",
        "A6E0681", "A4E00D9", "D2600CE", "EA6057E", "D5300D5", "5AA00CB", "76A037B", "96D00D3", "4AF0B83",
        "4AD00DB", "A4D00D0", "D0B1680", "D2500D7", "D5200CC", "DD4057C", "B5A00D4", "56D00C9", "55B027A",
        "49B00D2", "A570782", "A4B00D9", "AA500CE", "B25157E", "6D200D6", "ADA00CA", "4B6137B", "93700D3",
        "49F08C9", "49700DB", "64B00D0", "68A1680", "EA500D7", "6AA00CC", "A6C147C", "AAE00D4", "92E00CA",
        "D2E0379", "C9600D1", "D550781", "D4A00D9", "DA500CD", "5D5057E", "56A00D6", "A6D00CB", "55D047B",
        "52D00D3", "A9B0883", "A9500DB", "B4A00CF", "B6A067F", "AD500D7", "55A00CD", "ABA047C", "A5B00D4",
        "52B00CA", "B27037A", "69300D1", "7330781", "6AA00D9", "AD500CE", "4B5157E", "4B600D6", "A5700CB",
        "54E047C", "D1600D2", "E960882", "D5200DA", "DAA00CF", "6AA167F", "56D00D7", "4AE00CD", "A9D047D",
        "A2D00D4", "D1500C9", "F250279", "D5200D1", "DB20781", "B5A00D9", "55D00CF", "4DB0580", "49B00D7",
        "A4B00CC", "D4B047C", "AA500D4", "B550983", "6D200DB", "AD600D0", "5760681", "93700D8" }
    Gregorian = tostring(Gregorian)
    local Year, Month, Day, Pos, Data, MonthInfo, LeapInfo, Leap, Newyear, Sum, thisMonthInfo, GDate
    Year = tonumber(Gregorian.sub(Gregorian, 1, 4))
    Month = tonumber(Gregorian.sub(Gregorian, 5, 6))
    Day = tonumber(Gregorian.sub(Gregorian, 7, 8))
    if (Year > 2100 or Year < 1900 or Month > 12 or Month < 1 or Day > 30 or Day < 1 or string.len(Gregorian) < 8) then
        return "无效日期"
    end

    -- 获取当年农历数据
    Pos = (Year - 1899) + 1
    Data = LunarData[Pos]
    -- log.info(Data)
    -- 判断公历日期
    local tb1 = Analyze(Data)
    MonthInfo = tb1[1]
    LeapInfo = tb1[2]
    Leap = tb1[3]
    Newyear = tb1[4]
    -- 计算到当天到当年农历新年的天数
    Sum = 0

    if Leap > 0 then -- 有闰月
        thisMonthInfo = string.sub(MonthInfo, 1, Leap) .. LeapInfo .. string.sub(MonthInfo, Leap + 1)
        if (Leap ~= Month and tonumber(IsLeap) == 1) then
            return "该月不是闰月！"
        end
        if (Month <= Leap and tonumber(IsLeap) == 0) then
            for i = 1, Month - 1 do
                Sum = Sum + 29 + string.sub(thisMonthInfo, i, i)
            end
        else
            for i = 1, Month do
                Sum = Sum + 29 + string.sub(thisMonthInfo, i, i)
            end
        end
    else
        if (tonumber(IsLeap) == 1) then
            return "该年没有闰月！"
        end
        for i = 1, Month - 1 do
            thisMonthInfo = MonthInfo
            Sum = Sum + 29 + string.sub(thisMonthInfo, i, i)
        end
    end
    Sum = math.floor(Sum + Day - 1)
    GDate = Year .. Newyear
    GDate = GettotalDay(GDate, Sum)

    return GDate
end

local function main()
    log.info(LunarDate2Date(20210101, 0))
    -- log.info(19660808 .. "-" ..Date2LunarDate(19660808))
    -- log.info(20001218 .. "-" ..Date2LunarDate(20001218))
    log.info(os.date("%Y%m%d") .. "-" .. Date2LunarDate(os.date("%Y%m%d")))
    -- log.info(20200525 .. "-" ..Date2LunarDate(20200525))
    -- log.info(20220105 .. "-" ..Date2LunarDate(20220105))
    -- log.info(20350129 .. "-" ..Date2LunarDate(20350129))
end

-- main()

------------农历转换函数结束--------------

--[[
    --%a 星期简称，如Wed    %A 星期全称，如Wednesday
    --%b 月份简称，如Sep    %B 月份全称，如September
    --%c 日期时间格式 (e.g., 09/16/98 23:48:10)
    --%d 一个月的第几天 [01-31]    %j 一年的第几天
    --%H 24小时制 [00-23]    %I 12小时制 [01-12]
    --%M 分钟 [00-59]    %m 月份 (09) [01-12]
    --%p 上午/下午 (pm or am)
    --%S 秒 (10) [00-61]
    --%w 星期的第几天 [0-6 = Sunday-Saturday]    %W 一年的第几周
    --%x 日期格式 (e.g., 09/16/98)    %X 时间格式 (e.g., 23:48:10)
    --%Y 年份全称 (1998)    %y 年份简称 [00-99]
    --%% 百分号
    --os.date() 把时间戳转化成可显示的时间字符串
    --os.time ([table])
--]]

local format_Time = function()
    if os.date("%p") == "AM" then
        return "上午"
    else
        return "下午"
    end
end

function CnDate_translator(y)
    local t, cstr, t2
    cstr = { "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九" }
    t = ""
    for i = 1, y.len(y) do
        t2 = cstr[tonumber(y.sub(y, i, i)) + 1]
        if i == 5 and t2 ~= "〇" then
            t2 = "年十"
        elseif i == 5 and t2 == "〇" then
            t2 = "年"
        end
        if i == 6 and t2 ~= "〇" then
            t2 = t2 .. "月"
        elseif i == 6 and t2 == "〇" then
            t2 = "月"
        end
        -- if t.sub(t,t.len(t)-1)=="年" then t2=t2 .. "月" end
        if i == 7 and tonumber(y.sub(y, 7, 7)) > 1 then
            t2 = t2 .. "十"
        elseif i == 7 and t2 == "〇" then
            t2 = ""
        elseif i == 7 and tonumber(y.sub(y, 7, 7)) == 1 then
            t2 = "十"
        end
        if i == 8 and t2 ~= "〇" then
            t2 = t2 .. "日"
        elseif i == 8 and t2 == "〇" then
            t2 = "日"
        end
        t = t .. t2
    end
    return t
end

-- 年天数判断
function IsLeap(y)
    local year = tonumber(y)
    if math.floor(year % 400) ~= 0 and math.floor(year % 4) == 0 or math.floor(year % 400) == 0 then
        return 366
    else
        return 365
    end
end

-- 日历查询
local function QueryLunarInfo(date)
    local str, LunarDate, LunarGz, result, DateTime
    date = tostring(date)
    result = {}
    str = date:gsub("^(%u+)", "")
    if string.match(str, "^(20)%d%d+$") ~= nil or string.match(str, "^(19)%d%d+$") ~= nil then
        if string.len(str) == 4 then
            str = str .. "010101"
        elseif string.len(str) == 5 then
            str = str .. "10101"
        elseif string.len(str) == 6 then
            str = str .. "0101"
        elseif string.len(str) == 7 then
            str = str .. "101"
        elseif string.len(str) == 8 then
            str = str .. "01"
        elseif string.len(str) == 9 then
            str = str .. "0"
        else
            str = string.sub(str, 1, 10)
        end
        if tonumber(string.sub(str, 5, 6)) > 12 or tonumber(string.sub(str, 5, 6)) < 1 or
            tonumber(string.sub(str, 7, 8)) > 31 or tonumber(string.sub(str, 7, 8)) < 1 or
            tonumber(string.sub(str, 9, 10)) > 24 then
            return result
        end
        LunarDate = Date2LunarDate(str)
        LunarGz = lunarJzl(str)
        DateTime = LunarDate2Date(str, 0)
        dateRQ = string.sub(str, 1, 4) .. "年" .. string.sub(str, 5, 6) .. "月" .. string.sub(str, 7, 8) .. "日"

        if LunarGz ~= nil then
            local y = tonumber(string.sub(str, 1, 4))
            local m = tonumber(string.sub(str, 5, 6))
            local d = tonumber(string.sub(str, 7, 8))

            result = {
                -- ===== 公历格式 =====
                { dateRQ, "" },
                { string.sub(str, 1, 4) .. "." .. string.sub(str, 5, 6) .. "." .. string.sub(str, 7, 8), "" },
                { string.sub(str, 1, 4) .. "-" .. string.sub(str, 5, 6) .. "-" .. string.sub(str, 7, 8), "" },
                { string.sub(str, 1, 4) .. "/" .. string.sub(str, 5, 6) .. "/" .. string.sub(str, 7, 8), "" },
                { string.format("%d年%d月%d日", y, m, d), "" },
                { string.format("%d月%d日", m, d), "" },
                -- ===== 公历⇉农历 =====
                { LunarDate, "" },
                -- ===== 公历⇉干支 =====
                { LunarGz, "" }
            }
            if tonumber(string.sub(str, 7, 8)) < 31 then
                table.insert(result, { DateTime, "" })
                local leapDate = { LunarDate2Date(str, 1) .. "（闰）", "〔农历⇉公历〕" } --查询同一农历月份的闰月对应的公历日期
                if string.match(leapDate[1], "^(%d+)") ~= nil then
                    table.insert(result, leapDate)
                end
            end
        end
    end
    return result
end
--[[ ---------------测试----------------
local n=QueryLunarInfo(199105)
for i=1,#n do
    log.info(n[i][1]..n[i][2])
end
--]] ----------------------------------

--[[
-- 农历倒计时
local function nl_shengri(y, m, d)
  nlsrsj = y .. m .. d -- 农历时间
  date1 = os.date("%Y%m%d")
  date2 = LunarDate2Date(nlsrsj, 0)
  m = string.match(date2, "年(.-)月")
  if #m == "2" then
    date2 = string.gsub(date2, "年", "", "1")
  else
    date2 = string.gsub(date2, "年", "0", "1")
  end
  d = string.match(date2, "月(.-)日")
  if #d == "2" then
    date2 = string.gsub(date2, "月", "", "1")
  else
    date2 = string.gsub(date2, "月", "0", "1")
  end
  date2 = string.gsub(date2, "日", "", "1")

end

local function nl_shengri2(y, m, d)
  while nl_shengri(y, m, d) == -1 do
    y = tointeger(y + 1)
  end
  result = nl_shengri(y, m, d)
  return result
end  ]] --
-- 万象新增三伏天计算函数
-- 输入yyyymmdd返回:初伏(1)形式字符串
-- 起点：夏至之后(查询节气表找到夏至的日期)
-- 以夏至为起点向后遍历公历转农历，正则提取返回值以获取是否为庚日
-- 初伏：夏至起第3个庚日开始 ➔相隔10天
-- 中伏：初伏和末伏间隔，可能为10或者20天
-- 末伏：立秋起第1个庚日开始 ➔ 10天结束

-- 全局缓存表
local sanfu_cache = {}

-- 三伏天专用日期计算函数（无跨年处理）
function nextDayForSanfu(ymd, offset)
    offset = offset or 1
    local y = tonumber(ymd:sub(1, 4))
    local m = tonumber(ymd:sub(5, 6))
    local d = tonumber(ymd:sub(7, 8))

    -- 三伏天月份天数定义（6-9月）
    local month_days = {
        [6] = 30, -- 六月
        [7] = 31, -- 七月
        [8] = 31, -- 八月
        [9] = 30  -- 九月
    }
    -- 日期计算
    d = d + offset
    while true do
        local max_days = month_days[m] or 31 -- 默认为31天
        
        -- 日期在有效范围内
        if d <= max_days and d >= 1 then
            break
        end
        -- 超出本月天数（进入下个月）
        if d > max_days then
            d = d - max_days
            m = m + 1
        end
        -- 小于1（进入上个月）
        if d < 1 then
            m = m - 1
            d = d + (month_days[m] or 31)
        end
    end
    return string.format("%04d%02d%02d", y, m, d)
end
function buildSanfuCache(year)
    if sanfu_cache[year] then
        return sanfu_cache[year]
    end
    local jqs = GetNowTimeJq(tostring(year) .. "0101")

    -- 获取夏至和立秋
    local start_xiazhi, start_liqiu
    for _, item in ipairs(jqs) do
        local jq_name, jq_date = item:match("^(%S+)%s+(%d+%-%d+%-%d+)$")
        if jq_name == "夏至" then
            start_xiazhi = jq_date:gsub("-", "")
        elseif jq_name == "立秋" then
            start_liqiu = jq_date:gsub("-", "")
        end
    end

    if not start_xiazhi or not start_liqiu then return nil end

    local cache = {}

    -- 1. 计算初伏第一天（夏至后第三个庚日）
    local date = start_xiazhi
    local geng_count = 0
    local chufu_start
    while geng_count < 3 do
        local lunar_str = lunarJzl(date .. "12")
        -- 保留原始正则表达式匹配
        if lunar_str:match("月庚.*日") then
            geng_count = geng_count + 1
            if geng_count == 3 then
                chufu_start = date
            end
        end
        local _year = date:sub(1, 4)
        local _month = date:sub(5, 6)
        local _day = date:sub(7, 8)
        date = os.date("%Y%m%d", os.time({ year = _year, month = _month, day = tonumber(_day) + 1 }))
    end
 
    -- 2. 计算末伏第一天（立秋后第一个庚日）
    date = start_liqiu
    local mofu_start

    while not mofu_start do
        local lunar_str = lunarJzl(date .. "12")
        -- 保留原始正则表达式匹配
        if lunar_str:match("月庚.*日") then
            mofu_start = date
        end
        date = nextDayForSanfu(date) -- 使用专用日期函数
    end

    -- 3. 计算三伏天日期范围
    -- 初伏：10天
    for i = 0, 9 do
        local d = nextDayForSanfu(chufu_start, i)
        cache[d] = string.format("初伏(%d)", i + 1)
    end

    -- 末伏：10天
    for i = 0, 9 do
        local d = nextDayForSanfu(mofu_start, i)
        cache[d] = string.format("末伏(%d)", i + 1)
    end

    -- 中伏：从初伏结束次日到末伏开始前一天
    local zhongfu_start = nextDayForSanfu(chufu_start, 10)
    local zhongfu_end = nextDayForSanfu(mofu_start, -1)

    -- 使用专用日期函数计算中伏天数
    local current = zhongfu_start
    local zhongfu_days = 0
    while current <= zhongfu_end do
        zhongfu_days = zhongfu_days + 1
        cache[current] = string.format("中伏(%d)", zhongfu_days)
        current = nextDayForSanfu(current)
    end

    -- 缓存结果
    sanfu_cache[year] = cache

    return cache
end

-- 主查询函数
function get_sanfu_info(yyyymmdd)
    local year = string.sub(yyyymmdd, 1, 4)

    -- 构建或获取缓存
    local cache = sanfu_cache[year] or buildSanfuCache(year)
    if not cache then
        return nil
    end
    return cache[yyyymmdd]
end
-- 初始化函数：在部署时构建缓存
function initSanfuCache()
    if initialized then return end  -- 避免重复初始化
    
    -- 只初始化当前年份
    local current_year = os.date("%Y")
    buildSanfuCache(current_year)
    
    initialized = true
end
-- 在部署时调用此函数初始化缓存
initSanfuCache()
--三伏天计算结束


-- 万象修改的新的农历倒计时模块
-- 定义一个月映射表，采用明确的字符串键
local month_map = {
    ["正月"] = "01",
    ["二月"] = "02",
    ["三月"] = "03",
    ["四月"] = "04",
    ["五月"] = "05",
    ["六月"] = "06",
    ["七月"] = "07",
    ["八月"] = "08",
    ["九月"] = "09",
    ["十月"] = "10",
    ["冬月"] = "11",
    ["腊月"] = "12"
}

-- 功能：将农历日期转换为公历日期
local function nl_shengri(y, m, d)
    -- 获取当前日期
    local date1 = os.date("%Y%m%d")
    nlsrsj = y .. m .. d                  -- 农历时间
    -- 提取农历日期的年份
    local year = string.sub(nlsrsj, 1, 4) -- 提取“2015”从“20150621”

    -- 第二步：扩展为该年份的所有可能日期（每月15号）
    local dates = {}
    for month = 1, 12 do
        local date = year .. string.format("%02d", month) .. "15" -- 例如：20150115, 20150215...20151215取15日保险
        table.insert(dates, date)
    end

    -- 第三步：调用 Date2LunarDate 验证这些日期，检查是否为闰月
    local leap_month = nil                               -- 默认没有闰月
    for _, date in ipairs(dates) do
        local lunar_date = Date2LunarDate(os.date(date)) -- 返回:乙巳年(蛇)正月三十/

        if string.match(lunar_date, "闰") then
            local lunar_month = string.match(lunar_date, "(.-)月") -- 提取“闰”后面的月份
            leap_month = month_map[lunar_month] -- 闰月对应的数字（例如“闰二月” -> "02"）
        end
    end

    -- 第四步：从数字日期（如“20250607”）中提取月份02
    local lunar_month_str = string.sub(nlsrsj, 5, 6) -- 提取月份部分（如“02”）

    -- 第五步：根据已识别的闰月进行判断
    local lunar_month = lunar_month_str -- 直接使用提取的月份（例如“02”）

    -- 第六步：检查输入的农历月份是否为闰月
    local date2 = nil
    if leap_month and lunar_month == leap_month then
        -- 如果是闰月，传递1
        date2 = LunarDate2Date(nlsrsj, 1) -- 闰月传递1
    else
        -- 非闰月，传递0
        date2 = LunarDate2Date(nlsrsj, 0) -- 非闰月传递0
    end
    -- 继续处理年份和月份，格式化为公历格式
    m = string.match(date2, "年(.-)月")
    if #m == 2 then
        date2 = string.gsub(date2, "年", "", "1")
    else
        date2 = string.gsub(date2, "年", "0", "1")
    end
    d = string.match(date2, "月(.-)日")
    if #d == 2 then
        date2 = string.gsub(date2, "月", "", "1")
    else
        date2 = string.gsub(date2, "月", "0", "1")
    end
    date2 = string.gsub(date2, "日", "", "1")

    -- 计算日期差异
    result = diffDate(date1, date2)
    return result
end
-- 二次循环跨年调用
local function nl_shengri2(y, m, d)
    while nl_shengri(y, m, d) == -1 do
        y = math.floor(y + 1)
    end
    result = nl_shengri(y, m, d)
    return result
end

local function chinese_weekday(wday)
    local chinese_weekdays = { "周日", "周一", "周二", "周三", "周四", "周五", "周六" }
    return chinese_weekdays[wday + 1]
end
-- 获取中文星期（例如 "星期一"）都是为了利用现有函数
local function chinese_weekday2(week_day_num)
    local weekdays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" }
    return weekdays[week_day_num + 1]
end
-- ISO 8601 计算：返回当前日期是第几周，不使用os.date(%w)
local function iso_week_number(year, month, day)
    local function date_to_julian(y, m, d)
        -- 将年月日转换为儒略日（Julian Day Number）
        if m <= 2 then
            y = y - 1
            m = m + 12
        end
        local A = math.floor(y / 100)
        local B = 2 - A + math.floor(A / 4)
        return math.floor(365.25 * (y + 4716)) + math.floor(30.6001 * (m + 1)) + d + B - 1524.5
    end

    -- 获取当前日期的星期（ISO，周一为1，周日为7）
    local function get_iso_weekday(y, m, d)
        local t = os.time {
            year = y,
            month = m,
            day = d
        }
        local w = tonumber(os.date("%w", t))
        return (w == 0) and 7 or w
    end

    local jd = date_to_julian(year, month, day)
    local t = os.time {
        year = year,
        month = month,
        day = day
    }
    local iso_day = get_iso_weekday(year, month, day)

    -- 计算该日期所在的星期的周四（ISO周的基准点）
    local thursday_time = t + (4 - iso_day) * 86400
    local thursday = os.date("*t", thursday_time)

    -- 计算周数
    local first_thursday = os.time {
        year = thursday.year,
        month = 1,
        day = 4
    }
    local first_thursday_weekday = get_iso_weekday(thursday.year, 1, 4)
    local start_of_week1 = first_thursday - (first_thursday_weekday - 1) * 86400

    local week_number = math.floor((thursday_time - start_of_week1) / (7 * 86400)) + 1
    return thursday.year, week_number
end
-- 公历节日表（国际节日+中国传统公历节日）
local solar_holidays = {
    -- 国际节日
    ["元旦"] = "0101",
    ["情人节"] = "0214",
    ["妇女节"] = "0308",
    ["植树节"] = "0312",
    ["劳动节"] = "0501",
    ["青年节"] = "0504",
    ["儿童节"] = "0601",
    ["高考第一天"] = "0607",
    ["高考第二天"] = "0608",
    ["高考第三天"] = "0609",
    ["建党节"] = "0701",
    ["七七事变"] = "0707",
    ["建军节"] = "0801",
    ["教师节"] = "0910",
    ["国家公祭日"] = "0918",
    ["国庆节"] = "1001",
    -- 国际通用节日
    ["平安夜"] = "1224",
    ["圣诞节"] = "1225"
}

-- 农历节日表（中国传统节日）
local lunar_holidays = {
    ["春节"] = "0101", -- 正月初一
    ["元宵节"] = "0115", -- 正月十五
    ["龙抬头"] = "0202", -- 二月初二
    ["端午节"] = "0505", -- 五月初五
    ["七夕节"] = "0707", -- 七月初七
    ["中元节"] = "0715", -- 七月十五
    ["中秋节"] = "0815", -- 八月十五
    ["重阳节"] = "0909", -- 九月初九
    ["腊八节"] = "1208", -- 腊月初八
    ["小年"] = "1223" -- 腊月廿三
}

-- 获取指定月的第n个指定星期几
local function get_nth_weekday(year, month, weekday, n)
    -- 遍历1到31号日期
    for day = 1, 31 do
        -- 获取该日期
        local current_date = os.time({
            year = year,
            month = month,
            day = day
        })

        -- 如果超出当前月的天数，则结束
        if os.date("%m", current_date) ~= string.format("%02d", month) then
            break
        end
        -- 获取该日期是星期几
        local week_day_str = chinese_weekday2(tonumber(os.date("%w", current_date)))

        -- 判断是否是目标星期几
        if week_day_str == weekday then
            -- 减去1，因为要获取的是第n个目标星期几
            n = n - 1
            -- 如果找到了第n个目标星期几，返回该日期
            if n == 0 then
                return os.date("%Y%m%d", current_date) -- 返回日期的格式为 "YYYYMMDD"
            end
        end
    end
    return nil -- 如果没有找到，返回nil
end
-- 计算目标日期和当前日期的天数差
local function days_until(target_date)
    local current_date = os.date("%Y%m%d")           -- 获取当前日期 (yyyyMMdd)
    -- 去除返回值中的汉字，只保留数字部分
    target_date = target_date:gsub("%D", "")         -- 去除所有非数字字符
    local diff = diffDate(current_date, target_date) -- 计算当前日期与目标日期的天数差
    return diff                                      -- 返回天数差
end
-- 获取即将到来的节日（公历和农历）
local function get_upcoming_holidays()
    local upcoming_holidays = {}
    local current_year = os.date("%Y")

    -- 处理公历节日
    for holiday, date in pairs(solar_holidays) do
        local target_date = current_year .. date -- 当前年份的公历节日
        local days_left = days_until(target_date)
        if days_left >= 0 then
            -- 直接获取完整日期，格式为 "yyyy年mm月dd日"
            local m, d = target_date:sub(5, 6), target_date:sub(7, 8)
            local formatted_date = string.format("%s年%s月%s日", current_year, m, d)
            table.insert(upcoming_holidays, { holiday, formatted_date, days_left })
        end
    end
    -- 处理农历节日
    for holiday, lunar_date in pairs(lunar_holidays) do
        local days_ymd = os.date("%Y%m%d") -- 获取当前年月日
        -- 使用农历倒计时
        local countdown = nl_shengri2(os.date("%Y"), lunar_date:sub(1, 2), lunar_date:sub(3, 4))

        -- 如果倒计时为负，说明节日已过，需要加一年
        if countdown < 0 then
            countdown = nl_shengri2(os.date("%Y") + 1, lunar_date:sub(1, 2), lunar_date:sub(3, 4))
        end

        -- 使用倒计时和GettotalDay函数计算农历节日的公历日期
        local solar_date = GettotalDay(days_ymd, countdown)

        -- 直接使用完整的公历日期格式（假设 GettotalDay 返回 "yyyy年mm月dd日"）
        table.insert(upcoming_holidays, { holiday, solar_date, countdown })

        -- 如果是春节，计算除夕
        if holiday == "春节" then
            -- 计算春节的公历日期
            local year, month, day = solar_date:match("^(%d+)年(%d+)月(%d+)日")
            -- 将日期减去一天来获得除夕的日期
            local previous_day = os.time {
                year = tonumber(year),
                month = tonumber(month),
                day = tonumber(day)
            } - 24 * 60 * 60
            -- 格式化除夕的日期为 "yyyy年mm月dd日"
            local eve_date = os.date("%Y年%m月%d日", previous_day)
            -- 将除夕的日期插入到节日列表中
            table.insert(upcoming_holidays, { "除夕", eve_date, countdown - 1 })
        end
    end

    -- 感恩节：每年11月的第四个星期四
    local thanksgiving_date = get_nth_weekday(current_year, 11, "星期四", 4) -- 获取11月第四个星期四
    local thanksgiving_days_left = days_until(thanksgiving_date)
    if thanksgiving_days_left and thanksgiving_days_left >= 0 then
        -- 直接使用完整日期
        local formatted_date = thanksgiving_date:sub(1, 4) .. "年" .. thanksgiving_date:sub(5, 6) .. "月" ..
            thanksgiving_date:sub(7, 8) .. "日"
        table.insert(upcoming_holidays, { "感恩节", formatted_date, thanksgiving_days_left })
    end

    -- 母亲节：每年5月的第二个星期日
    local mothers_day_date = get_nth_weekday(current_year, 5, "星期日", 2) -- 获取5月第二个星期日
    local mothers_day_days_left = days_until(mothers_day_date)
    if mothers_day_days_left and mothers_day_days_left >= 0 then
        -- 直接使用完整日期
        local formatted_date = mothers_day_date:sub(1, 4) .. "年" .. mothers_day_date:sub(5, 6) .. "月" ..
            mothers_day_date:sub(7, 8) .. "日"
        table.insert(upcoming_holidays, { "母亲节", formatted_date, mothers_day_days_left })
    end

    -- 父亲节：每年6月的第三个星期日
    local fathers_day_date = get_nth_weekday(current_year, 6, "星期日", 3) -- 获取6月第三个星期日
    local fathers_day_days_left = days_until(fathers_day_date)
    if fathers_day_days_left and fathers_day_days_left >= 0 then
        -- 直接使用完整日期
        local formatted_date = fathers_day_date:sub(1, 4) .. "年" .. fathers_day_date:sub(5, 6) .. "月" ..
            fathers_day_date:sub(7, 8) .. "日"
        table.insert(upcoming_holidays, { "父亲节", formatted_date, fathers_day_days_left })
    end

    -- 获取所有节气
    local jqs = GetNowTimeJq(os.date("%Y%m%d", os.time())) -- 获取节气
    -- 遍历所有节气
    for _, jq_info in ipairs(jqs) do
        -- 使用正则匹配节气名称和日期（假设日期格式为 yyyy-mm-dd）
        local jq_name, jq_date = jq_info:match("^(%S+)%s+(%d+%-%d+%-%d+)$") -- 匹配节气名称和日期
        -- 如果是清明节
        if jq_name == "清明" then
            -- 直接使用完整日期
            local formatted_date = jq_date:gsub("%-", "") -- 去掉日期中的"-"
            local days_left = days_until(formatted_date)  -- 获取距离清明节的天数
            -- 格式化为 "yyyy年mm月dd日"
            formatted_date = jq_date:sub(1, 4) .. "年" .. jq_date:sub(6, 7) .. "月" .. jq_date:sub(9, 10) .. "日"
            table.insert(upcoming_holidays, { "清明节", formatted_date, days_left })
        end
    end

    -- 按照距离最近的天数排序
    table.sort(upcoming_holidays, function(a, b)
        return a[3] < b[3]
    end)

    return upcoming_holidays
end

-- 获取生日提醒信息的函数，可接受自定义生日设置
function get_birthday_reminders(custom_settings)
    -- 使用传入的自定义设置或默认全局设置
    local settings = custom_settings or BIRTHDAY_SETTINGS

    -- 获取当前日期
    local current_date = os.date("%Y%m%d")
    local current_year = os.date("%Y")
    local birthday_list = {}

    -- 计算公历生日倒计时
    for _, birthday in ipairs(settings.solar or {}) do
        local month, day, name, note = birthday[1], birthday[2], birthday[3], birthday[4]
        -- 构建今年的生日日期
        local this_year_birthday = string.format("%s%02d%02d", current_year, month, day)
        -- 计算天数差
        local days_left = diffDate(current_date, this_year_birthday)

        -- 如果生日已过，计算明年的生日
        if days_left < 0 then
            local next_year = tonumber(current_year) + 1
            this_year_birthday = string.format("%s%02d%02d", next_year, month, day)
            days_left = diffDate(current_date, this_year_birthday)
        end

        -- 格式化日期显示
        local formatted_date = string.format("%02d月%02d日", month, day)
        -- 构建生日信息
        local birthday_info
        if note and note ~= "" then
            birthday_info = string.format("%s(%s): %s", name, note, formatted_date)
        else
            birthday_info = string.format("%s: %s", name, formatted_date)
        end

        -- 添加到生日列表
        table.insert(birthday_list,
            { birthday_info, string.format("〔< %d 天〕", days_left), days_left })
    end

    -- 计算农历生日倒计时
    for _, birthday in ipairs(settings.lunar or {}) do
        local month, day, name, note = birthday[1], birthday[2], birthday[3], birthday[4]

        -- 在函数内重新定义农历月份名和日期名
        local cMonName = { "正月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月",
            "十月", "冬月", "腊月" }
        local cDayName = { "初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九",
            "初十", "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八",
            "十九", "二十", "廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七",
            "廿八", "廿九", "三十" }

        -- 格式化农历月日
        local lunar_md = string.format("%02d%02d", month, day)

        -- 先计算今年的农历生日对应的公历日期
        local lunar_date_str = current_year .. lunar_md
        local solar_date = LunarDate2Date(lunar_date_str, 0)

        -- 提取公历日期中的月份和日期
        local solar_month, solar_day = solar_date:match("(%d+)月(%d+)日")
        solar_month = tonumber(solar_month)
        solar_day = tonumber(solar_day)

        -- 构建今年农历生日对应的公历日期字符串
        local this_year_birthday = string.format("%s%02d%02d", current_year, solar_month, solar_day)
        -- 计算今年农历生日倒计时天数
        local days_left = diffDate(current_date, this_year_birthday)

        -- 如果今年农历生日已过，计算明年的农历生日
        if days_left < 0 then
            local next_year = tonumber(current_year) + 1
            lunar_date_str = next_year .. lunar_md
            solar_date = LunarDate2Date(lunar_date_str, 0)
            solar_month, solar_day = solar_date:match("(%d+)月(%d+)日")
            solar_month = tonumber(solar_month)
            solar_day = tonumber(solar_day)
            days_left = nl_shengri2(current_year, lunar_md, "00")
        end

        -- 格式化农历日期
        local formatted_lunar = cMonName[month] .. cDayName[day]
        local formatted_solar = string.format("%d月%d日", tonumber(solar_month), tonumber(solar_day))

        -- 构建农历生日信息
        local birthday_info
        if note and note ~= "" then
            birthday_info = string.format("%s(%s): %s(%s)", name, note, formatted_lunar, formatted_solar)
        else
            birthday_info = string.format("%s: %s(%s)", name, formatted_lunar, formatted_solar)
        end

        -- 添加到生日列表
        table.insert(birthday_list,
            { birthday_info, string.format("〔 < %d 天〕", days_left), days_left })
    end

    -- 按天数排序
    table.sort(birthday_list, function(a, b)
        return a[3] < b[3]
    end)

    -- 移除days_left数据，保持与原始数据结构兼容
    for i, v in ipairs(birthday_list) do
        birthday_list[i] = { v[1], v[2] }
    end

    return birthday_list
end

-- 下面这个用于统一生成候选的逻辑
local function generate_candidates(input, seg, candidates)
    for _, item in ipairs(candidates) do
        local candidate = Candidate(input, seg.start, seg._end, item[1], item[2])
        candidate.quality = 1000000 -- 设定高优先级
        yield(candidate)
    end
end

-- 判断指定年月日是否合法
local function DateExists(year, month, day)
    local days
    if IsLeap(year) > 365 then
        days = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    else
        days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    end
    return month >= 1 and month <= 12 and day >= 1 and day <= days[month]
end

-- 设置 segment 提示
local function set_prompt_if_invalid(context, msg)
    local segment = context.composition:back()
    if segment then
        segment.prompt = msg
    end
end

---@param input string
---@param seg Segment
---@param env Env
local function translator(input, seg, env)
    local engine  = env.engine
    local context = engine.context
    local config  = engine.schema.config
    local segment = context.composition:back()

    if input:sub(1, 1) == "N" then
        local n = input:sub(2)
        local yr = os.date("%Y")
        segment.tags = segment.tags + Set({ "Ndate" })

        -- N0101–N1231（仅月日）
        if #n == 4 and n:match("^%d%d%d%d$") then
            --- 设置手动排序的排序编码，以启用手动排序支持
            context:set_property("sequence_adjustment_code", "Nmmdd")

            local mm = tonumber(n:sub(1, 2))
            local dd = tonumber(n:sub(3, 4))
            if mm and dd and mm >= 1 and mm <= 12 and dd >= 1 and dd <= 31 then
                local display_year = " 〔" .. yr .. "年" .. "〕"

                if not DateExists(yr, mm, dd) then
                    set_prompt_if_invalid(context, " 〔日期不存在〕")
                    return
                end
                -- 如果日期存在，则设置为 display_year
                set_prompt_if_invalid(context, display_year)
                local mm_str = string.format("%02d", mm)
                local dd_str = string.format("%02d", dd)
                local date_str = yr .. mm_str .. dd_str .. "01"
                local lunar = QueryLunarInfo(date_str)
                if #lunar > 0 then
                    local candidates = {
                        { string.format("%d月%d日", mm, dd), "" },
                        { string.format("%02d月%02d日", mm, dd), "" }
                    }
                    local lunar_full = lunar[7][1]
                    local lunar_md = lunar_full:gsub(".*%)", "")
                    if lunar_md == lunar_full then
                        local lunar_md = lunar_full:gsub("^.-年", ""):gsub("^.-%)", "")
                    end
                    table.insert(candidates, { lunar_md, "" })

                    local gz_full = lunar[8][1]
                    local gz_md = gz_full:gsub("^.-年", "")
                    table.insert(candidates, { gz_md, "" })

                    generate_candidates(input, seg, candidates)
                end
                return
            end
        end

        -- N2025 或 N20250101 等
        if n:match("^(20)%d%d") or n:match("^(19)%d%d") then
            --- 设置手动排序的排序编码，以启用手动排序支持
            context:set_property("sequence_adjustment_code", "N")

            if #n >= 8 then
                local yyyy = tonumber(n:sub(1, 4))
                local mm = tonumber(n:sub(5, 6))
                local dd = tonumber(n:sub(7, 8))
                if not DateExists(yyyy, mm, dd) then
                    set_prompt_if_invalid(context, " 〔日期不存在〕")
                    return
                end
            end
            local lunar = QueryLunarInfo(n)
            local candidates = {}
            for i = 1, #lunar do
                table.insert(candidates, { lunar[i][1], lunar[i][2] })
            end
            generate_candidates(input, seg, candidates)
            return
        end
    end

    -- 以下为需要通过 shijian_keys 触发的功能
    local shijian_keys_config = config:get_list("key_binder/shijian_keys")
    local is_sijian_input = false
    local command = ""

    if not shijian_keys_config then
        return
    end

    for i = 0, shijian_keys_config.size - 1 do
        local key = shijian_keys_config:get_value_at(i).value
        local key_length = string.len(key)
        if string.sub(input, 1, key_length) == key then
            is_sijian_input = true
            command = string.sub(input, key_length + 1)
            break
        end
    end

    if is_sijian_input ~= true or command == "" then
        return
    end

    segment.tags = segment.tags + Set({ "shijian" })

    -- **日期候选项**
    if (command == "rq") then
        --- 设置手动排序的排序编码，以启用手动排序支持
        context:set_property("sequence_adjustment_code", "/rq")

        local today = os.date("*t") -- 当前时间表
        local ymd = os.date("%Y%m%d") -- 年月日
        local ymdh = os.date("%Y%m%d%H") -- 年月日时
        local num_year = string.format(" 〔%03d/%d〕", today.yday, IsLeap(today.year)) -- 年内第几天/总天数
        local m = today.month
        local d = today.day

        local date_variants = {
            -- 常规格式（带前导零）
            { os.date("%Y年%m月%d日"), "" },
            { os.date("%Y.%m.%d"), "" },
            { os.date("%Y-%m-%d"), "" },
            { os.date("%Y/%m/%d"), "" },
            { os.date("%Y%m%d"), "" },
            -- 不带前导零的格式
            { string.format("%d年%d月%d日", today.year, m, d), "" },
            { string.format("%d月%d日", m, d), "" },
            -- 农历相关
            { CnDate_translator(ymd), "" },
            { lunarJzl(ymdh), "" },
            { Date2LunarDate(ymd) .. JQtest(ymd), "" },
            { Date2LunarDate(ymd) .. GetLunarSichen(os.date("%H"), 1), "" }
        }
        generate_candidates("date", seg, date_variants)
        set_prompt_if_invalid(context, num_year)
        return
    end

    -- **时间候选项**
    if (command == "sj" or command == "uj") then
        --- 设置手动排序的排序编码，以启用手动排序支持
        context:set_property("sequence_adjustment_code", "/sj")

        local time_discrpt = " 〔" .. GetLunarSichen(os.date("%H"), 1) .. "〕"
        local time_variants = { { os.date("%H:%M"), "" }, --同一个时间首选看到时辰即可
            { format_Time() .. os.date("%I:%M"), "" },
            { os.date("%H:%M:%S"), "" },
            { string.gsub(os.date("%H点%M分%S秒"), "^0", ""), "" } }
        generate_candidates("time", seg, time_variants)
        set_prompt_if_invalid(context, time_discrpt)
        return
    end

    -- **农历候选项**
    if (command == "nl") then
        --- 设置手动排序的排序编码，以启用手动排序支持
        context:set_property("sequence_adjustment_code", "/nl")

        local yr = os.date("%Y")
        local year = "〔" .. yr .. "年" .. "〕" -- 构造提示字符串

        local lunar_variants = {
            { Date2LunarDate(os.date("%Y%m%d")) .. JQtest(os.date("%Y%m%d")),        "" },
            { lunarJzl(os.date("%Y%m%d%H")),                                         "" },
            { Date2LunarDate(os.date("%Y%m%d")) .. GetLunarSichen(os.date("%H"), 1), "" }
        }
        generate_candidates("date", seg, lunar_variants)
        set_prompt_if_invalid(context, year) -- 显示“〔2025年〕”风格的提示
        return
    end

    if (command == "xq") then
        --- 设置手动排序的排序编码，以启用手动排序支持
        context:set_property("sequence_adjustment_code", "/xq")

        local now = os.date("*t")
        local _, weekno = iso_week_number(now.year, now.month, now.day)
        local num_weekday = "〔第 " .. weekno .. " 周〕"

        local week_variants = {
            { chinese_weekday2(os.date("%w")), num_weekday },
            { chinese_weekday(os.date("%w")),  num_weekday } }
        generate_candidates("xq", seg, week_variants)
        return
    end

    -- **第几周**
    if (command == "ww") then
        --- 设置手动排序的排序编码，以启用手动排序支持
        context:set_property("sequence_adjustment_code", "/ww")

        local now = os.date("*t")
        local _, weekno = iso_week_number(now.year, now.month, now.day)
        local weekno_str = tostring(weekno)

        local week_variants = { { "W" .. weekno_str, "" }, { "第" .. weekno_str .. "周", "" } }
        generate_candidates("oww", seg, week_variants)
        return
    end

    -- **节气候选项**
    if (command == "jq") then
        --- 设置手动排序的排序编码，以启用手动排序支持
        context:set_property("sequence_adjustment_code", "/jq")

        local jqs = GetNowTimeJq(os.date("%Y%m%d", os.time() - 3600 * 24 * 15))
        local jq_variants = {}
        for _, jq in ipairs(jqs) do
            table.insert(jq_variants, { jq, "" }) -- 空注释
        end
        generate_candidates("ojq", seg, jq_variants)
        return
    end

    -- **时间戳**
    if (command == "tt") then
        --- 设置手动排序的排序编码，以启用手动排序支持
        context:set_property("sequence_adjustment_code", "/tt")

        local current_time = os.time()
        local timestamp_variants = { { string.format('%d', current_time), "〔时间戳〕" } }
        generate_candidates("time", seg, timestamp_variants)
        return
    end

    -- **日期+时间**
    if (command == "rs") then
        --- 设置手动排序的排序编码，以启用手动排序支持
        context:set_property("sequence_adjustment_code", "/rs")

        local current_time = os.time()
        local time_variants = { { os.date('%Y-%m-%d %H:%M:%S', current_time), "〔年-月-日 时:分:秒〕" },
            { os.date('%Y-%m-%dT%H:%M:%S+08:00', current_time), "〔年-月-日T时:分:秒+时区〕" },
            { os.date('%Y%m%d%H%M%S', current_time), "〔年月日时分秒〕" } }
        generate_candidates("time", seg, time_variants)
        return
    end

    -- **节日查询**
    if (command == "jr") then
        --- 设置手动排序的排序编码，以启用手动排序支持
        context:set_property("sequence_adjustment_code", "/jr")

        local upcoming_holidays = get_upcoming_holidays() -- 获取所有即将到来的节日
        local candidates = {}
        -- 格式化输出节日信息
        for _, holiday in ipairs(upcoming_holidays) do
            -- 提取公历日期中的月份和日期部分（假设日期格式为 "yyyy年mm月dd日"）
            local year, month, day = holiday[2]:match("^(%d+)年(%d+)月(%d+)日")
            -- 格式化为 "mm月dd日"
            if month and day then
                local formatted_date = string.format("%02d月%02d日", tonumber(month), tonumber(day))
                -- 输出格式：节日名称（格式化后的公历日期） 还有多少天
                local holiday_summary = string.format("%s (%s)", holiday[1], formatted_date, holiday[3])
                local holiday_diff = string.format("〔< %d 天〕", holiday[3]) -- 差值显示到注释里面
                -- 将节日信息加入候选项列表
                table.insert(candidates, { holiday_summary, holiday_diff })
            end
        end
        -- 使用 generate_candidates 函数生成候选项
        generate_candidates("holiday_summary", seg, candidates)
        return
    end

    -- **生日提醒**
    if (command == "sr" or command == "ur") then
        --- 设置手动排序的排序编码，以启用手动排序支持
        context:set_property("sequence_adjustment_code", "/sr")

        -- 从用户配置文件中读取生日设置
        local birthday_settings = {
            solar = {},
            lunar = {}
        }

        -- 读取公历生日（键值对格式）
        local solar_map = config:get_map("birthday_reminder/solar_birthdays")
        if solar_map then
            -- 使用 keys() 方法获取所有键
            local keys = solar_map:keys()
            for _, key in ipairs(keys) do
                -- 使用 get_value(key) 方法获取值
                local value = solar_map:get_value(key):get_string()

                -- 解析值：日期和备注（格式："日期,备注" 或 "日期"）
                local parts = {}
                for part in string.gmatch(value, "[^,]+") do
                    table.insert(parts, part)
                end

                local date_str = parts[1] or ""
                local note = parts[2] or ""

                -- 解析日期字符串
                date_str = string.format("%04d", tonumber(date_str) or 0)
                local month = tonumber(date_str:sub(1, 2))
                local day = tonumber(date_str:sub(3, 4))

                -- 添加到生日设置
                table.insert(birthday_settings.solar, { month, day, key, note })
            end
        end

        -- 读取农历生日（键值对格式）
        local lunar_map = config:get_map("birthday_reminder/lunar_birthdays")
        if lunar_map then
            -- 使用 keys() 方法获取所有键
            local keys = lunar_map:keys()
            for _, key in ipairs(keys) do
                -- 使用 get_value(key) 方法获取值
                local value = lunar_map:get_value(key):get_string()

                -- 解析值：日期和备注（格式："日期,备注" 或 "日期"）
                local parts = {}
                for part in string.gmatch(value, "[^,]+") do
                    table.insert(parts, part)
                end

                local date_str = parts[1] or ""
                local note = parts[2] or ""

                -- 解析日期字符串
                date_str = string.format("%04d", tonumber(date_str) or 0)
                local month = tonumber(date_str:sub(1, 2))
                local day = tonumber(date_str:sub(3, 4))

                -- 添加到生日设置
                table.insert(birthday_settings.lunar, { month, day, key, note })
            end
        end

        local candidates = get_birthday_reminders(birthday_settings)
        -- 生成候选项
        generate_candidates("birthday_reminders", seg, candidates)
        return
    end

    -- **日历信息整合处理**
    if (command == "day") then
        -- 获取当前时间
        local now = os.time()
        local year = tonumber(os.date("%Y", now))
        local month = tonumber(os.date("%m", now))
        local day = tonumber(os.date("%d", now))
        local day_of_year = tonumber(os.date("%j", now)) -- 今年的第几天
        local date_table = os.date("*t", now)
        local _, week_of_year = iso_week_number(date_table.year, date_table.month, date_table.day)
        local week_of_month = math.ceil(tonumber(os.date("%d", now)) / 7) -- 当月的第几周

        -- 计算一年的总天数，判断是否为闰年
        local days_in_year = IsLeap(year) == "闰年" and 366 or 365 -- 判断是否为闰年
        local year_progress = (day_of_year / days_in_year) * 100 -- 今年进度
        -- 获取星期数据
        local week_day_str = chinese_weekday2(os.date("%w")) -- 获取中文星期（例如 "星期三"）
        -- 获取农历数据
        local lunar_info_str = Date2LunarDate(os.date("%Y%m%d")) -- 获取农历的天干地支和生肖等

        -- 获取最近的三个节气
        local jqs = GetNowTimeJq(os.date("%Y%m%d", now))
        local upcoming_jqs = {}
        local zero_jieqi = nil -- 记录今天的节气

        -- 计算距离某个节气的天数
        local function days_until_jieqi(jieqi)
            local jieqi_date = jieqi:match("(%d+-%d+-%d+)$") -- 提取节气日期部分
            local target_time = jieqi_date:gsub("-", "")
            local diff_days = days_until(target_time)
            return diff_days
        end
        -- 遍历候选中最近的 3 个节气，原因是上面向后计算了一个节气
        for i = 1, math.min(3, #jqs) do
            local jieqi = jqs[i]
            local diff_days = days_until_jieqi(jieqi)

            if diff_days == 0 then
                local jieqi_name = jieqi:match("^(%S+)")
                zero_jieqi = jieqi_name -- 记录今天的节气
            elseif diff_days > 0 then
                table.insert(upcoming_jqs, jieqi)
            end
        end

        -- 获取每个节气的距离天数
        local jieqi_days = {}
        for _, jieqi in ipairs(upcoming_jqs) do
            table.insert(jieqi_days, days_until_jieqi(jieqi))
        end

        -- 计算距离下一年1月1日的天数
        local next_year = year + 1
        local new_year_time = os.time({
            year = next_year,
            month = 1,
            day = 1,
            hour = 0,
            min = 0,
            sec = 0
        })
        local diff_days_next_year = math.floor((new_year_time - now) / (24 * 3600))

        -- 遍历前三个节日并返回节日名称、日期、倒计时天数
        local upcoming_holidays = get_upcoming_holidays() or {}
        local holiday_data = {}
        local zero_holiday = nil -- 独立存储 holiday[3] == 0 的节日名称

        local filtered_holidays = {}
        local zero_found = false

        for i = 1, math.min(3, #upcoming_holidays) do
            local holiday = upcoming_holidays[i]

            if holiday[3] == 0 then
                zero_holiday = holiday[1] -- 记录这个节日名称
                zero_found = true
            else
                table.insert(filtered_holidays, holiday)
            end
        end

        if zero_found then
            -- 只存储后两个节日
            for i = math.max(1, #filtered_holidays - 1), #filtered_holidays do
                local holiday = filtered_holidays[i]
                local year, month, day = holiday[2]:match("^(%d+)年(%d+)月(%d+)日")

                if year and month and day then
                    local formatted_date = string.format("%04d-%02d-%02d", tonumber(year), tonumber(month),
                        tonumber(day))
                    table.insert(holiday_data, { holiday[1], formatted_date, holiday[3] })
                end
            end
        else
            -- 存储前两个节日
            for i = 1, math.min(2, #filtered_holidays) do
                local holiday = filtered_holidays[i]
                local year, month, day = holiday[2]:match("^(%d+)年(%d+)月(%d+)日")

                if year and month and day then
                    local formatted_date = string.format("%04d-%02d-%02d", tonumber(year), tonumber(month),
                        tonumber(day))
                    table.insert(holiday_data, { holiday[1], formatted_date, holiday[3] })
                end
            end
        end
        -- 获取三伏天
        local sanfu = get_sanfu_info(os.date("%Y%m%d", now)) or ""
        -- 生成问候语函数
        local function get_greeting()
            local current_hour = tonumber(os.date("%H"))
            local greeting = ""

            if current_hour >= 0 and current_hour < 6 then
                greeting = "晚安!"
            elseif current_hour >= 6 and current_hour < 12 then
                greeting = "早上好!"
            elseif current_hour >= 12 and current_hour < 14 then
                greeting = "午安!"
            elseif current_hour >= 14 and current_hour < 18 then
                greeting = "下午好!"
            else
                greeting = "晚上好!"
            end

            return greeting
        end

        local greeting = get_greeting() -- 获取问候语
        -- 进度条格式化
        local function generate_progress_bar(percentage)
            percentage = math.min(100, math.max(0, percentage))                       -- 限制百分比在0-100
            local total_blocks = 10
            local filled_blocks = math.floor((percentage / 100) * total_blocks + 0.5) -- 四舍五入计算块数
            local empty_blocks = total_blocks - filled_blocks

            return string.rep("▓", filled_blocks) .. string.rep("▒", empty_blocks) ..
                string.format(" %.1f%%", percentage)
        end
        local progress_bar = generate_progress_bar(year_progress)
        -- 生成自定义长度的符号线
        local function generate_line(length)
            return string.rep("—", length)
        end

        -- 你可以根据需要调整长度
        local line = generate_line(14) -- 控制符号线的宽度为 50
        -- 生成最终信息字符串
        local summary = string.format("※嗨，我是万象小助手，%s\n", greeting) .. line .. "\n" ..
            string.format("☉ 今天是：%s%s%s\n", zero_holiday or "", zero_jieqi or "", sanfu) ..
            string.format("☉ %d年%d月%d日 %s\n", year, month, day, week_day_str) ..
            string.format("☉ 农历：%s\n", lunar_info_str) .. line .. "\n" ..
            string.format("◉ %d进度：\n", year) .. string.format("◈%s\n", progress_bar) ..
            string.format("◈ 本年第[ %d ]周，本月第[ %d ]周\n", week_of_year, week_of_month) ..
            string.format("◈ 距 %d 年： [ %d ]天\n", next_year, diff_days_next_year) ..
            string.format("◈ 今年已过[ %d ]天\n", day_of_year - 1) ..
            string.format("◈ 今天是第[ %d ]天\n", day_of_year) .. line .. "\n" ..
            string.format("◉ 倒数日：\n") ..
            string.format("◈ %s %s < [ %d ]天\n", holiday_data[1][1], holiday_data[1][2],
                holiday_data[1][3]) ..
            string.format("◈ %s %s < [ %d ]天\n", holiday_data[2][1], holiday_data[2][2],
                holiday_data[2][3]) .. string.format("◈ %s < [ %d ]天\n", upcoming_jqs[1], jieqi_days[1]) ..
            string.format("◈ %s < [ %d ]天", upcoming_jqs[2], jieqi_days[2])
        -- 使用 generate_candidates 函数生成候选项
        local candidates = { { summary, "" } -- 空注释
        }
        -- 调用 generate_candidates 来提交候选项
        generate_candidates("day_summary", seg, candidates)
        return
    end
    -- 取消tag
    segment.tags = segment.tags - Set({ "shijian" })
end
return translator
