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

模块:Chinese calendar:修订间差异

来自奇葩栖息地
添加731字节 、​ 2025年1月7日 (星期二)
无编辑摘要
(//Edit via InPageEdit)
标签手工回退
无编辑摘要
标签已被回退
第1行:
local p = {}
 
-- 位运算模拟函数
-- 农历数据表
local lunarInfofunction =rshift(a, {b)
if b < 0 then return lshift(a, -b) end
0x04bd8,
return math.floor(a / (2 ^ b))
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
}
 
local function lshift(a, b)
-- 天干
if b < 0 then return rshift(a, -b) end
local Gan = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" }
return a * (2 ^ b)
 
end
-- 地支
local Zhi = { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" }
 
-- 月份
local nStr3 = { "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊" }
 
-- 日期
local nStr2 = { "初", "十", "廿", "卅" }
local nStr1 = { "日", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" }
 
-- 实现位运算函数
local function band(a, b)
if not a or not b then return 0 end
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
第233行 ⟶ 第20行:
end
bitval = bitval * 2
a = math.floor(a / 2)
b = math.floor(b / 2)
end
return result
end
 
-- 农历数据表
local function rshift(a, b)
local calendar = {
if not a or not b then return 0 end
lunarInfo = { 0x04bd8,
if a <= 0 then return 0 end
if b < 0 then return a end0x04ae0,
0x0a570,
return math.floor(a / (2^b))
0x054d5,
end
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 = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" },
-- 计算农历闰月月份
Zhi = { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" },
local function leapMonth(y)
Animals = { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" },
if y < 1900 or y > 2100 then return 0 end
nStr1 = { "日", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" },
local index = y - 1900
nStr2 = { "初", "十", "廿", "卅" },
if index < 0 or index >= #lunarInfo then return 0 end
nStr3 = { "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊" }
return band(lunarInfo[index], 0xf)
}
end
 
-- 计算农历闰月天核心转换函
local function leapDayscalendar.solar2lunar(y, m, d)
-- 边界检查
if y < 1900 or y > 2100 then return 0 end
if y < 1900 or y > 2100 then return nil end
local m = leapMonth(y)
if y == 1900 and m == 01 and d < 31 then return 0nil end
if band(lunarInfo[y - 1900], 0x10000) ~= 0 then
return 30
end
return 29
end
 
-- 计算农历距离19001月31日的总天数
local objDate = os.time({ year = y, month = m, day = d })
local function lYearDays(y)
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 targetDateoffset = osmath.timefloor({(objDate year- =baseDate) y,/ month(24 =* m, day =60 d* }60))
 
local offset = math.floor((targetDate - baseDate) / (24 * 60 * 60))
local i, temp, leap = 1900, 0, 0
 
-- 计算农历年
while i < 2101 and offset > 0 do
local ly = 1900
local temp = 0calendar.lYearDays(i)
while ly < 2101 and offset > 0 do
temp = lYearDays(ly)
offset = offset - temp
lyi = lyi + 1
end
 
if offset < 0 then
offset = offset + temp
lyi = lyi - 1
end
 
local year = i
-- 计算农历月日
leap = calendar.leapMonth(year)
local lm = 1
local ld = 1
local isLeap = false
local leap = leapMonth(ly)
 
-- 计算月
i = 1
while offset > 0 and lm < 13 do
while i < 13 and offset > 0 do
if leap > 0 and lm == leap + 1 and not isLeap then
if leap > 0 lmand i == lm(leap -+ 1) and isLeap == false then
i = i - 1
isLeap = true
temp = calendar.leapDays(lyyear)
else
temp = calendar.monthDays(lyyear, lmi)
end
 
if isLeap == true and i == (leap + 1) then
isLeap = false
end
 
offset = offset - temp
if isLeap and lmi == leapi + 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
lmi = lmi - 1
end
end
 
if offset < 0 then
offset = offset + temp
lmi = lmi - 1
end
ld = offset + 1
 
local month = i
-- 格式化输出
local gzYearday = Gan[((ly - 4) % 10) + 1] .. Zhi[((ly - 4) % 12)offset + 1]
 
local lMonth = nStr3[lm]
localreturn lDay{
if ld == 10 thenlYear = year,
lDaylMonth = "初十"month,
elseif ld == 20 thenlDay = day,
lDayisLeap = "二十"isLeap
}
elseif ld == 30 then
end
lDay = "三十"
 
-- 辅助函数
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
end
end
return sum + calendar.leapDays(y)
end
 
function calendar.leapMonth(y)
return band(calendar.lunarInfo[y - 1900], 0xf)
end
 
function calendar.leapDays(y)
if calendar.leapMonth(y) ~= 0 then
return band(calendar.lunarInfo[y - 1900], 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
lDayresult = nStr2[mathresult ..floor(ld / 10) + 1calendar.nStr2[4] .. calendar.nStr1[ld % 10lunar.lDay +- 130]
end
 
return gzYear .. "年" .. lMonth .. "月" .. lDayresult
end
 
2,099

个编辑