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

模块:Chinese calendar:修订间差异

来自奇葩栖息地
删除808字节 、​ 2025年1月9日 (星期四)
//Edit via InPageEdit
(// Edit via Wikiplus)
标签已被回退
(//Edit via InPageEdit)
标签手工回退
第1行:
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)
aif =not tonumber(a) or not b then return 0 end
b = tonumber(b) or 0
local result = 0
local bitval = 1
 
-- 转换为正整数处理负数或0的情况
if a <= 0 or b <= 0 then return 0 end
a = math.floor(math.abs(a))
b = math.floor(math.abs(b))
 
while a > 0 orand b > 0 do
if a % 2 == 1 and b % 2 == 1 then
result = result + bitval
第23行 ⟶ 第239行:
end
 
local function rshift(a, b)
-- 农历数据表
if not a or not b then return 0 end
local calendar = {
if a <= 0 then return 0 end
lunarInfo = { 0x04bd8,
if b < 0 0x04ae0,then return a end
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 },
 
-- 计算农历闰月月份
Gan = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" },
local function leapMonth(y)
Zhi = { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" },
if y < 1900 or y > 2100 then return 0 end
Animals = { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" },
local index = y - 1900
nStr1 = { "日", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" },
if index < 0 or index >= #lunarInfo then return 0 end
nStr2 = { "初", "十", "廿", "卅" },
return band(lunarInfo[index], 0xf)
nStr3 = { "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊" }
end
}
 
-- 核心转换函计算农历闰月天
local function calendar.solar2lunarleapDays(y, m, d)
if y < 1900 or y > 2100 then return 0 end
-- 边界检查
local m = leapMonth(y)
if y < 1900 or y > 2100 then return nil end
if y == 1900 and m == 1 and d < 310 then return nil0 end
if band(lunarInfo[y - 1900], 0x10000) ~= 0 then
return 30
end
return 29
end
 
-- 计算距离1900农历1月31日的总天数
local function lYearDays(y)
local objDate = os.time({ year = y, month = m, day = d })
if y < 1900 or y > 2100 then return 0 end
local sum = 348
local i = 0x8000
local idx = y - 1900
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
if band(lunarInfo[y - 1900], 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 offsettargetDate = mathos.floortime((objDate{ -year baseDate)= /y, (24month *= 60m, day = *d 60)})
local offset = math.floor((targetDate - baseDate) / (24 * 60 * 60))
 
local i, temp, leap = 1900, 0, 0
 
-- 计算农历年
local ly = 1900
while i < 2101 and offset > 0 do
local temp = calendar.lYearDays(i)0
while ly < 2101 and offset > 0 do
temp = lYearDays(ly)
offset = offset - temp
ily = ily + 1
end
 
if offset < 0 then
offset = offset + temp
ily = ily - 1
end
 
-- 计算农历月日
local year = i
local lm = 1
leap = calendar.leapMonth(year)
local ld = 1
local isLeap = false
local leap = leapMonth(ly)
 
-- 计算月
while offset > 0 and lm < 13 do
i = 1
if leap > 0 and lm == leap + 1 and not isLeap then
while i < 13 and offset > 0 do
if leap > 0 and ilm == (leaplm +- 1) and isLeap == false then
i = i - 1
isLeap = true
temp = calendar.leapDays(yearly)
else
temp = calendar.monthDays(yearly, ilm)
end
 
if isLeap == true and i == (leap + 1) then
isLeap = false
end
 
offset = offset - temp
iif isLeap and lm == ileap + 1 then isLeap = false end
lm = lm + 1
end
 
-- 计算日
if offset == 0 and leap > 0 and i == leap + 1 then
if offset == 0 and leap > 0 and lm == leap + 1 then
if isLeap then
isLeap = false
else
isLeap = true
ilm = ilm - 1
end
end
 
if offset < 0 then
offset = offset + temp
ilm = ilm - 1
end
ld = offset + 1
 
-- 格式化输出
local month = i
local daygzYear = offsetGan[((ly - 4) % 10) + 1] .. Zhi[((ly - 4) % 12) + 1]
local lMonth = nStr3[lm]
 
returnlocal {lDay
if ld == 10 lYear = year,then
lMonthlDay = month,"初十"
elseif ld == 20 lDay = day,then
isLeaplDay = isLeap"二十"
elseif ld == 30 then
}
lDay = "三十"
end
 
-- 辅助函数
function calendar.lYearDays(y)
local sum = 348
local info = calendar.lunarInfo[y - 1900]
if not info then return 0 end
 
for i = 0x8000, 0x8, -1 do
if band(info, i) ~= 0 then
sum = sum + 1
end
end
return sum + calendar.leapDays(y)
end
 
function calendar.leapMonth(y)
local info = calendar.lunarInfo[y - 1900]
if not info then return 0 end
return band(info, 0xf)
end
 
function calendar.leapDays(y)
local info = calendar.lunarInfo[y - 1900]
if not info then return 0 end
if calendar.leapMonth(y) ~= 0 then
return band(info, 0x10000) ~= 0 and 30 or 29
end
return 0
end
 
-- MediaWiki接口
function p.toLunar(frame)
local date = frame.args[1] or frame.args.date
if not date then
return '参数错误'
end
 
local y, m, d = date:match("(%d+)%-(%d+)%-(%d+)")
y, m, d = tonumber(y), tonumber(m), tonumber(d)
 
if not (y and m and d) then
return '日期格式错误'
end
 
local lunar = calendar.solar2lunar(y, m, d)
if not lunar then
return '超出计算范围(1900-2100)'
end
 
local result = calendar.Gan[(lunar.lYear - 4) % 10 + 1] ..
calendar.Zhi[(lunar.lYear - 4) % 12 + 1] .. '年'
 
if lunar.isLeap then
result = result .. '闰'
end
 
result = result .. calendar.nStr3[lunar.lMonth] .. '月'
 
if lunar.lDay < 11 then
result = result .. calendar.nStr2[1] .. calendar.nStr1[lunar.lDay]
elseif lunar.lDay < 20 then
result = result .. calendar.nStr2[2] .. calendar.nStr1[lunar.lDay - 10]
elseif lunar.lDay == 20 then
result = result .. calendar.nStr2[2] .. calendar.nStr2[2]
elseif lunar.lDay < 30 then
result = result .. calendar.nStr2[3] .. calendar.nStr1[lunar.lDay - 20]
else
resultlDay = result .. calendar.nStr2[4math.floor(ld / 10) + 1] .. calendar.nStr1[lunar.lDayld % 10 -+ 301]
end
 
return resultgzYear .. "年" .. lMonth .. "月" .. lDay
end
 
2,099

个编辑