欢迎来到奇葩栖息地!欢迎加入Discord服务器:XfrfHCzfbW请先至特殊:参数设置验证邮箱后再进行编辑。特殊:参数设置挑选自己想要使用的小工具!不会编辑?请至这里学习Wikitext语法。

模块:Chinese calendar:修订间差异

来自奇葩栖息地
添加的内容 删除的内容
无编辑摘要
标签已被回退
(//Edit via InPageEdit)
 
(未显示同一用户的3个中间版本)
第1行: 第1行:
local p = {}
local p = {}


-- 农历数据表
-- 位运算模拟函数
local function rshift(a, b)
local lunarInfo = {
0x04bd8,
if b < 0 then return lshift(a, -b) end
0x04ae0,
return math.floor(a / (2 ^ b))
0x0a570,
end
0x054d5,
0x0d260,
0x0d950,
0x16554,
0x056a0,
0x09ad0,
0x055d2,
0x04ae0,
0x0a5b6,
0x0a4d0,
0x0d250,
0x1d255,
0x0b540,
0x0d6a0,
0x0ada2,
0x095b0,
0x14977,
0x04970,
0x0a4b0,
0x0b4b5,
0x06a50,
0x06d40,
0x1ab54,
0x02b60,
0x09570,
0x052f2,
0x04970,
0x06566,
0x0d4a0,
0x0ea50,
0x06e95,
0x05ad0,
0x02b60,
0x186e3,
0x092e0,
0x1c8d7,
0x0c950,
0x0d4a0,
0x1d8a6,
0x0b550,
0x056a0,
0x1a5b4,
0x025d0,
0x092d0,
0x0d2b2,
0x0a950,
0x0b557,
0x06ca0,
0x0b550,
0x15355,
0x04da0,
0x0a5b0,
0x14573,
0x052b0,
0x0a9a8,
0x0e950,
0x06aa0,
0x0aea6,
0x0ab50,
0x04b60,
0x0aae4,
0x0a570,
0x05260,
0x0f263,
0x0d950,
0x05b57,
0x056a0,
0x096d0,
0x04dd5,
0x04ad0,
0x0a4d0,
0x0d4d4,
0x0d250,
0x0d558,
0x0b540,
0x0b6a0,
0x195a6,
0x095b0,
0x049b0,
0x0a974,
0x0a4b0,
0x0b27a,
0x06a50,
0x06d40,
0x0af46,
0x0ab60,
0x09570,
0x04af5,
0x04970,
0x064b0,
0x074a3,
0x0ea50,
0x06b58,
0x055c0,
0x0ab60,
0x096d5,
0x092e0,
0x0c960,
0x0d954,
0x0d4a0,
0x0da50,
0x07552,
0x056a0,
0x0abb7,
0x025d0,
0x092d0,
0x0cab5,
0x0a950,
0x0b4a0,
0x0baa4,
0x0ad50,
0x055d9,
0x04ba0,
0x0a5b0,
0x15176,
0x052b0,
0x0a930,
0x07954,
0x06aa0,
0x0ad50,
0x05b52,
0x04b60,
0x0a6e6,
0x0a4e0,
0x0d260,
0x0ea65,
0x0d530,
0x05aa0,
0x076a3,
0x096d0,
0x04afb,
0x04ad0,
0x0a4d0,
0x1d0b6,
0x0d250,
0x0d520,
0x0dd45,
0x0b5a0,
0x056d0,
0x055b2,
0x049b0,
0x0a577,
0x0a4b0,
0x0aa50,
0x1b255,
0x06d20,
0x0ada0,
0x14b63,
0x09370,
0x049f8,
0x04970,
0x064b0,
0x168a6,
0x0ea50,
0x06b20,
0x1a6c4,
0x0aae0,
0x0a2e0,
0x0d2e3,
0x0c960,
0x0d557,
0x0d4a0,
0x0da50,
0x05d55,
0x056a0,
0x0a6d0,
0x055d4,
0x052d0,
0x0a9b8,
0x0a950,
0x0b4a0,
0x0b6a6,
0x0ad50,
0x055a0,
0x0aba4,
0x0a5b0,
0x052b0,
0x0b273,
0x06930,
0x07337,
0x06aa0,
0x0ad50,
0x14b55,
0x04b60,
0x0a570,
0x054e4,
0x0d160,
0x0e968,
0x0d520,
0x0daa0,
0x16aa6,
0x056d0,
0x04ae0,
0x0a9d4,
0x0a2d0,
0x0d150,
0x0f252,
0x0d520
}


-- 天干
local function lshift(a, b)
local Gan = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" }
if b < 0 then return rshift(a, -b) end
return a * (2 ^ b)
end


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

-- 月份
local nStr3 = { "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊" }

-- 日期
local nStr2 = { "初", "十", "廿", "卅" }
local nStr1 = { "日", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" }

-- 实现位运算函数
local function band(a, b)
local function band(a, b)
if not a or not b then
return 0
end

-- Localize math.floor for performance
local floor = math.floor
local result = 0
local result = 0
local bitval = 1
local bitval = 1

-- 处理负数或0的情况
if a <= 0 or b <= 0 then
return 0
end

while a > 0 and b > 0 do
while a > 0 and b > 0 do
if a % 2 == 1 and b % 2 == 1 then
if a % 2 == 1 and b % 2 == 1 then
result = result + bitval
result = result + bitval
end
end

bitval = bitval * 2
bitval = bitval * 2
a = math.floor(a / 2)
a = floor(a/2)
b = math.floor(b / 2)
b = floor(b/2)
end
end

return result
return result
end
end


local function rshift(a, b)
-- 农历数据表
if not a or not b then
local calendar = {
return 0
lunarInfo = { 0x04bd8,
0x04ae0,
end
0x0a570,
0x054d5,
0x0d260,
0x0d950,
0x16554,
0x056a0,
0x09ad0,
0x055d2,
0x04ae0,
0x0a5b6,
0x0a4d0,
0x0d250,
0x1d255,
0x0b540,
0x0d6a0,
0x0ada2,
0x095b0,
0x14977,
0x04970,
0x0a4b0,
0x0b4b5,
0x06a50,
0x06d40,
0x1ab54,
0x02b60,
0x09570,
0x052f2,
0x04970,
0x06566,
0x0d4a0,
0x0ea50,
0x06e95,
0x05ad0,
0x02b60,
0x186e3,
0x092e0,
0x1c8d7,
0x0c950,
0x0d4a0,
0x1d8a6,
0x0b550,
0x056a0,
0x1a5b4,
0x025d0,
0x092d0,
0x0d2b2,
0x0a950,
0x0b557,
0x06ca0,
0x0b550,
0x15355,
0x04da0,
0x0a5b0,
0x14573,
0x052b0,
0x0a9a8,
0x0e950,
0x06aa0,
0x0aea6,
0x0ab50,
0x04b60,
0x0aae4,
0x0a570,
0x05260,
0x0f263,
0x0d950,
0x05b57,
0x056a0,
0x096d0,
0x04dd5,
0x04ad0,
0x0a4d0,
0x0d4d4,
0x0d250,
0x0d558,
0x0b540,
0x0b6a0,
0x195a6,
0x095b0,
0x049b0,
0x0a974,
0x0a4b0,
0x0b27a,
0x06a50,
0x06d40,
0x0af46,
0x0ab60,
0x09570,
0x04af5,
0x04970,
0x064b0,
0x074a3,
0x0ea50,
0x06b58,
0x055c0,
0x0ab60,
0x096d5,
0x092e0,
0x0c960,
0x0d954,
0x0d4a0,
0x0da50,
0x07552,
0x056a0,
0x0abb7,
0x025d0,
0x092d0,
0x0cab5,
0x0a950,
0x0b4a0,
0x0baa4,
0x0ad50,
0x055d9,
0x04ba0,
0x0a5b0,
0x15176,
0x052b0,
0x0a930,
0x07954,
0x06aa0,
0x0ad50,
0x05b52,
0x04b60,
0x0a6e6,
0x0a4e0,
0x0d260,
0x0ea65,
0x0d530,
0x05aa0,
0x076a3,
0x096d0,
0x04afb,
0x04ad0,
0x0a4d0,
0x1d0b6,
0x0d250,
0x0d520,
0x0dd45,
0x0b5a0,
0x056d0,
0x055b2,
0x049b0,
0x0a577,
0x0a4b0,
0x0aa50,
0x1b255,
0x06d20,
0x0ada0,
0x14b63,
0x09370,
0x049f8,
0x04970,
0x064b0,
0x168a6,
0x0ea50,
0x06b20,
0x1a6c4,
0x0aae0,
0x0a2e0,
0x0d2e3,
0x0c960,
0x0d557,
0x0d4a0,
0x0da50,
0x05d55,
0x056a0,
0x0a6d0,
0x055d4,
0x052d0,
0x0a9b8,
0x0a950,
0x0b4a0,
0x0b6a6,
0x0ad50,
0x055a0,
0x0aba4,
0x0a5b0,
0x052b0,
0x0b273,
0x06930,
0x07337,
0x06aa0,
0x0ad50,
0x14b55,
0x04b60,
0x0a570,
0x054e4,
0x0d160,
0x0e968,
0x0d520,
0x0daa0,
0x16aa6,
0x056d0,
0x04ae0,
0x0a9d4,
0x0a2d0,
0x0d150,
0x0f252,
0x0d520 },


if a <= 0 then
Gan = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" },
return 0
Zhi = { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" },
end
Animals = { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" },
nStr1 = { "日", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" },
nStr2 = { "初", "十", "廿", "卅" },
nStr3 = { "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊" }
}


if b < 0 then
-- 核心转换函数
return a
function calendar.solar2lunar(y, m, d)
-- 边界检查
end
if y < 1900 or y > 2100 then return nil end
if y == 1900 and m == 1 and d < 31 then return nil end


return math.floor(a / (2^b))
-- 计算距离1900年1月31日的总天数
end
local objDate = os.time({ year = y, month = m, day = d })
local baseDate = os.time({ year = 1900, month = 1, day = 31 })
local offset = math.floor((objDate - baseDate) / (24 * 60 * 60))


-- 计算农历闰月月份
local i, temp, leap = 1900, 0, 0
local function leapMonth(y)

if y < 1900 or y > 2100 then
-- 计算农历年
return 0
while i < 2101 and offset > 0 do
temp = calendar.lYearDays(i)
offset = offset - temp
i = i + 1
end
end


-- Lua table index starts from 1
if offset < 0 then
offset = offset + temp
local index = y - 1900 + 1

i = i - 1
-- Lua table index starts from 1
if index <= 0 or index > #lunarInfo then
return 0
end
end


return band(lunarInfo[index], 0xf)
local year = i
end
leap = calendar.leapMonth(year)
local isLeap = false


-- 计算月
-- 计算农历闰天数
local function leapDays(y)
i = 1
while i < 13 and offset > 0 do
if y < 1900 or y > 2100 then
return 0
if leap > 0 and i == (leap + 1) and isLeap == false then
end
i = i - 1
isLeap = true
temp = calendar.leapDays(year)
else
temp = calendar.monthDays(year, i)
end


local m = leapMonth(y)
if isLeap == true and i == (leap + 1) then
isLeap = false
end


offset = offset - temp
if m == 0 then
i = i + 1
return 0
end
end


-- Lua table index starts from 1
if offset == 0 and leap > 0 and i == leap + 1 then
if isLeap then
if band(lunarInfo[y - 1900 + 1], 0x10000) ~= 0 then
isLeap = false
return 30
else
isLeap = true
i = i - 1
end
end
end


return 29
if offset < 0 then
end
offset = offset + temp

i = i - 1
-- 计算农历年天数
local function lYearDays(y)
if y < 1900 or y > 2100 then
return 0
end
end


local month = i
local sum = 348
local day = offset + 1
local i = 0x8000
-- Lua table index starts from 1
local idx = y - 1900 + 1


-- Lua table index starts from 1
return {
lYear = year,
if idx <= 0 or idx > #lunarInfo then
return 0
lMonth = month,
lDay = day,
end
isLeap = isLeap
}
end


while i > 0x8 do
-- 辅助函数
if band(lunarInfo[idx], i) ~= 0 then
function calendar.lYearDays(y)
local sum = 348
for i = 0x8000, 0x8, -1 do
i = rshift(i, 1)
if band(calendar.lunarInfo[y - 1900], i) ~= 0 then
sum = sum + 1
sum = sum + 1
end
end

i = rshift(i, 1)
end
end
return sum + calendar.leapDays(y)
end


return sum + leapDays(y)
function calendar.leapMonth(y)
return band(calendar.lunarInfo[y - 1900], 0xf)
end
end


-- 计算农历月份天数
function calendar.leapDays(y)
local function monthDays(y, m)
if calendar.leapMonth(y) ~= 0 then
return band(calendar.lunarInfo[y - 1900], 0x10000) ~= 0 and 30 or 29
if y < 1900 or y > 2100 then
return 0
end
end

return 0
if m > 12 or m < 1 then
return 0
end

-- Lua table index starts from 1
if band(lunarInfo[y - 1900 + 1], rshift(0x10000, m)) ~= 0 then
return 30
end

return 29
end
end


-- 主要的转换函数
-- MediaWiki接口
function p.toLunar(frame)
function p.toLunar(frame)
-- 解析输入日期
local date = frame.args[1] or frame.args.date
local date = frame.args[1] or frame:getParent().args.date

if not date then
if not date then
return '参数错误'
return "日期参数错误"
end

local y, m, d = date:match("^(%d%d%d%d)-(%d%d?)-(%d%d?)$")

if not y or not m or not d then
return "日期格式错误"
end
end


local y, m, d = date:match("(%d+)%-(%d+)%-(%d+)")
y, m, d = tonumber(y), tonumber(m), tonumber(d)
y, m, d = tonumber(y), tonumber(m), tonumber(d)


-- 验证日期范围
if not (y and m and d) then
return '日期格式错误'
if y < 1900 or y > 2100 then
return "年份超出范围(1900-2100)"
end
end


if m < 1 or m > 12 then
local lunar = calendar.solar2lunar(y, m, d)
return "月份错误"
if not lunar then
return '超出计算范围(1900-2100)'
end
end


if d < 1 or d > 31 then
local result = calendar.Gan[(lunar.lYear - 4) % 10 + 1] ..
return "日期错误"
calendar.Zhi[(lunar.lYear - 4) % 12 + 1] .. '年'
end


-- 计算距离1900年1月31日的天数
if lunar.isLeap then
local baseDate = os.time({ year = 1900, month = 1, day = 31 })
result = result .. '闰'
local targetDate = os.time({ year = y, month = m, day = d })
local offset = math.floor((targetDate - baseDate) / (24 * 60 * 60))

-- 计算农历年
local ly = 1900
local temp = 0

while ly < 2101 and offset > 0 do
temp = lYearDays(ly)
offset = offset - temp
ly = ly + 1
end
end


if offset < 0 then
result = result .. calendar.nStr3[lunar.lMonth] .. '月'
offset = offset + temp
ly = ly - 1
end


-- 计算农历月日
if lunar.lDay < 11 then
local lm = 1
result = result .. calendar.nStr2[1] .. calendar.nStr1[lunar.lDay]
elseif lunar.lDay < 20 then
local ld = 1
local isLeap = false
result = result .. calendar.nStr2[2] .. calendar.nStr1[lunar.lDay - 10]
local leap = leapMonth(ly)
elseif lunar.lDay == 20 then

result = result .. calendar.nStr2[2] .. calendar.nStr2[2]
-- 计算月
elseif lunar.lDay < 30 then
while offset > 0 and lm < 13 do
result = result .. calendar.nStr2[3] .. calendar.nStr1[lunar.lDay - 20]
if leap > 0 and lm == leap + 1 and not isLeap then
lm = lm - 1
isLeap = true
temp = leapDays(ly)
else
temp = monthDays(ly, lm)
end

offset = offset - temp

if isLeap and lm == leap + 1 then
isLeap = false
end

lm = lm + 1
end

-- 计算日
if offset == 0 and leap > 0 and lm == leap + 1 then
if isLeap then
isLeap = false
else
isLeap = true
lm = lm - 1
end
end

if offset < 0 then
offset = offset + temp
lm = lm - 1
end

ld = offset + 1

-- 格式化输出
local gzYear = Gan[((ly - 4) % 10) + 1] .. Zhi[((ly - 4) % 12) + 1]
local lMonth = nStr3[lm]
local lDay

if ld == 10 then
lDay = "初十"
elseif ld == 20 then
lDay = "二十"
elseif ld == 30 then
lDay = "三十"
else
else
result = result .. calendar.nStr2[4] .. calendar.nStr1[lunar.lDay - 30]
lDay = nStr2[math.floor(ld / 10) + 1] .. nStr1[ld % 10 + 1]
end
end


return result
return gzYear .. "年" .. lMonth .. "月" .. lDay
end
end



2025年1月9日 (四) 11:55的最新版本

[创建 | 历史 | 清除缓存]文档页面
此模块没有文档页面。如果你知道此模块的使用方法,请帮助为其创建文档页面。
local p = {}

-- 农历数据表
local lunarInfo = {
    0x04bd8,
    0x04ae0,
    0x0a570,
    0x054d5,
    0x0d260,
    0x0d950,
    0x16554,
    0x056a0,
    0x09ad0,
    0x055d2,
    0x04ae0,
    0x0a5b6,
    0x0a4d0,
    0x0d250,
    0x1d255,
    0x0b540,
    0x0d6a0,
    0x0ada2,
    0x095b0,
    0x14977,
    0x04970,
    0x0a4b0,
    0x0b4b5,
    0x06a50,
    0x06d40,
    0x1ab54,
    0x02b60,
    0x09570,
    0x052f2,
    0x04970,
    0x06566,
    0x0d4a0,
    0x0ea50,
    0x06e95,
    0x05ad0,
    0x02b60,
    0x186e3,
    0x092e0,
    0x1c8d7,
    0x0c950,
    0x0d4a0,
    0x1d8a6,
    0x0b550,
    0x056a0,
    0x1a5b4,
    0x025d0,
    0x092d0,
    0x0d2b2,
    0x0a950,
    0x0b557,
    0x06ca0,
    0x0b550,
    0x15355,
    0x04da0,
    0x0a5b0,
    0x14573,
    0x052b0,
    0x0a9a8,
    0x0e950,
    0x06aa0,
    0x0aea6,
    0x0ab50,
    0x04b60,
    0x0aae4,
    0x0a570,
    0x05260,
    0x0f263,
    0x0d950,
    0x05b57,
    0x056a0,
    0x096d0,
    0x04dd5,
    0x04ad0,
    0x0a4d0,
    0x0d4d4,
    0x0d250,
    0x0d558,
    0x0b540,
    0x0b6a0,
    0x195a6,
    0x095b0,
    0x049b0,
    0x0a974,
    0x0a4b0,
    0x0b27a,
    0x06a50,
    0x06d40,
    0x0af46,
    0x0ab60,
    0x09570,
    0x04af5,
    0x04970,
    0x064b0,
    0x074a3,
    0x0ea50,
    0x06b58,
    0x055c0,
    0x0ab60,
    0x096d5,
    0x092e0,
    0x0c960,
    0x0d954,
    0x0d4a0,
    0x0da50,
    0x07552,
    0x056a0,
    0x0abb7,
    0x025d0,
    0x092d0,
    0x0cab5,
    0x0a950,
    0x0b4a0,
    0x0baa4,
    0x0ad50,
    0x055d9,
    0x04ba0,
    0x0a5b0,
    0x15176,
    0x052b0,
    0x0a930,
    0x07954,
    0x06aa0,
    0x0ad50,
    0x05b52,
    0x04b60,
    0x0a6e6,
    0x0a4e0,
    0x0d260,
    0x0ea65,
    0x0d530,
    0x05aa0,
    0x076a3,
    0x096d0,
    0x04afb,
    0x04ad0,
    0x0a4d0,
    0x1d0b6,
    0x0d250,
    0x0d520,
    0x0dd45,
    0x0b5a0,
    0x056d0,
    0x055b2,
    0x049b0,
    0x0a577,
    0x0a4b0,
    0x0aa50,
    0x1b255,
    0x06d20,
    0x0ada0,
    0x14b63,
    0x09370,
    0x049f8,
    0x04970,
    0x064b0,
    0x168a6,
    0x0ea50,
    0x06b20,
    0x1a6c4,
    0x0aae0,
    0x0a2e0,
    0x0d2e3,
    0x0c960,
    0x0d557,
    0x0d4a0,
    0x0da50,
    0x05d55,
    0x056a0,
    0x0a6d0,
    0x055d4,
    0x052d0,
    0x0a9b8,
    0x0a950,
    0x0b4a0,
    0x0b6a6,
    0x0ad50,
    0x055a0,
    0x0aba4,
    0x0a5b0,
    0x052b0,
    0x0b273,
    0x06930,
    0x07337,
    0x06aa0,
    0x0ad50,
    0x14b55,
    0x04b60,
    0x0a570,
    0x054e4,
    0x0d160,
    0x0e968,
    0x0d520,
    0x0daa0,
    0x16aa6,
    0x056d0,
    0x04ae0,
    0x0a9d4,
    0x0a2d0,
    0x0d150,
    0x0f252,
    0x0d520
}

-- 天干
local Gan = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" }

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

-- 月份
local nStr3 = { "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊" }

-- 日期
local nStr2 = { "初", "十", "廿", "卅" }
local nStr1 = { "日", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" }

-- 实现位运算函数
local function band(a, b)
    if not a or not b then
    	return 0
    end

    -- Localize math.floor for performance
    local floor = math.floor
    local result = 0
    local bitval = 1

    -- 处理负数或0的情况
    if a <= 0 or b <= 0 then
    	return 0
    end

    while a > 0 and b > 0 do
        if a % 2 == 1 and b % 2 == 1 then
            result = result + bitval
        end

        bitval = bitval * 2
        a = floor(a/2)
        b = floor(b/2)
    end

    return result
end

local function rshift(a, b)
    if not a or not b then
    	return 0
    end

    if a <= 0 then
    	return 0
    end

    if b < 0 then
    	return a
    end

    return math.floor(a / (2^b))
end

-- 计算农历闰月月份
local function leapMonth(y)
    if y < 1900 or y > 2100 then
    	return 0
    end

	-- Lua table index starts from 1
    local index = y - 1900 + 1

	-- Lua table index starts from 1
    if index <= 0 or index > #lunarInfo then
    	return 0
    end

    return band(lunarInfo[index], 0xf)
end

-- 计算农历闰月天数
local function leapDays(y)
    if y < 1900 or y > 2100 then
    	return 0
    end

    local m = leapMonth(y)

    if m == 0 then
    	return 0
    end

	-- Lua table index starts from 1
    if band(lunarInfo[y - 1900 + 1], 0x10000) ~= 0 then
        return 30
    end

    return 29
end

-- 计算农历年天数
local function lYearDays(y)
    if y < 1900 or y > 2100 then
    	return 0
    end

    local sum = 348
    local i = 0x8000
	-- Lua table index starts from 1
    local idx = y - 1900 + 1

	-- Lua table index starts from 1
    if idx <= 0 or idx > #lunarInfo then
    	return 0
    end

    while i > 0x8 do
        if band(lunarInfo[idx], i) ~= 0 then
            sum = sum + 1
        end

        i = rshift(i, 1)
    end

    return sum + leapDays(y)
end

-- 计算农历月份天数
local function monthDays(y, m)
    if y < 1900 or y > 2100 then
    	return 0
    end

    if m > 12 or m < 1 then
    	return 0
    end

	-- Lua table index starts from 1
    if band(lunarInfo[y - 1900 + 1], rshift(0x10000, m)) ~= 0 then
        return 30
    end

    return 29
end

-- 主要的转换函数
function p.toLunar(frame)
    -- 解析输入日期
    local date = frame.args[1] or frame:getParent().args.date

    if not date then
    	return "日期参数错误"
    end

    local y, m, d = date:match("^(%d%d%d%d)-(%d%d?)-(%d%d?)$")

    if not y or not m or not d then
        return "日期格式错误"
    end

    y, m, d = tonumber(y), tonumber(m), tonumber(d)

    -- 验证日期范围
    if y < 1900 or y > 2100 then
        return "年份超出范围(1900-2100)"
    end

    if m < 1 or m > 12 then
        return "月份错误"
    end

    if d < 1 or d > 31 then
        return "日期错误"
    end

    -- 计算距离1900年1月31日的天数
    local baseDate = os.time({ year = 1900, month = 1, day = 31 })
    local targetDate = os.time({ year = y, month = m, day = d })
    local offset = math.floor((targetDate - baseDate) / (24 * 60 * 60))

    -- 计算农历年
    local ly = 1900
    local temp = 0

    while ly < 2101 and offset > 0 do
        temp = lYearDays(ly)
        offset = offset - temp
        ly = ly + 1
    end

    if offset < 0 then
        offset = offset + temp
        ly = ly - 1
    end

    -- 计算农历月日
    local lm = 1
    local ld = 1
    local isLeap = false
    local leap = leapMonth(ly)

    -- 计算月
    while offset > 0 and lm < 13 do
        if leap > 0 and lm == leap + 1 and not isLeap then
            lm = lm - 1
            isLeap = true
            temp = leapDays(ly)
        else
            temp = monthDays(ly, lm)
        end

        offset = offset - temp

        if isLeap and lm == leap + 1 then
        	isLeap = false
        end

        lm = lm + 1
    end

    -- 计算日
    if offset == 0 and leap > 0 and lm == leap + 1 then
        if isLeap then
            isLeap = false
        else
            isLeap = true
            lm = lm - 1
        end
    end

    if offset < 0 then
        offset = offset + temp
        lm = lm - 1
    end

    ld = offset + 1

    -- 格式化输出
    local gzYear = Gan[((ly - 4) % 10) + 1] .. Zhi[((ly - 4) % 12) + 1]
    local lMonth = nStr3[lm]
    local lDay

    if ld == 10 then
        lDay = "初十"
    elseif ld == 20 then
        lDay = "二十"
    elseif ld == 30 then
        lDay = "三十"
    else
        lDay = nStr2[math.floor(ld / 10) + 1] .. nStr1[ld % 10 + 1]
    end

    return gzYear .. "年" .. lMonth .. "月" .. lDay
end

return p