欢迎来到奇葩栖息地!欢迎加入Discord服务器:XfrfHCzfbW。请先至特殊:参数设置验证邮箱后再进行编辑。在特殊:参数设置挑选自己想要使用的小工具!不会编辑?请至这里学习Wikitext语法。
模块:Chinese calendar:修订间差异
来自奇葩栖息地
添加的内容 删除的内容
SkyEye FAST(讨论 | 贡献) 无编辑摘要 标签:已被回退 |
SkyEye FAST(讨论 | 贡献) (// Edit via Wikiplus) 标签:已被回退 |
||
第2行: | 第2行: | ||
-- 位运算模拟函数 |
-- 位运算模拟函数 |
||
local function rshift(a, b) |
|||
⚫ | |||
⚫ | |||
end |
|||
local function lshift(a, b) |
|||
⚫ | |||
⚫ | |||
end |
|||
local function band(a, b) |
local function band(a, b) |
||
a = tonumber(a) or 0 |
|||
b = tonumber(b) or 0 |
|||
local result = 0 |
local result = 0 |
||
local bitval = 1 |
local bitval = 1 |
||
⚫ | |||
-- 转换为正整数处理 |
|||
a = math.floor(math.abs(a)) |
|||
⚫ | |||
⚫ | |||
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 |
a = math.floor(a/2) |
||
b = math.floor(b |
b = math.floor(b/2) |
||
end |
end |
||
return result |
return result |
||
第314行: | 第311行: | ||
function calendar.lYearDays(y) |
function calendar.lYearDays(y) |
||
local sum = 348 |
local sum = 348 |
||
⚫ | |||
⚫ | |||
for i = 0x8000, 0x8, -1 do |
for i = 0x8000, 0x8, -1 do |
||
if band(info, i) ~= 0 then |
|||
⚫ | |||
sum = sum + 1 |
sum = sum + 1 |
||
end |
end |
||
第324行: | 第323行: | ||
function calendar.leapMonth(y) |
function calendar.leapMonth(y) |
||
local info = calendar.lunarInfo[y - 1900] |
|||
⚫ | |||
⚫ | |||
end |
end |
||
function calendar.leapDays(y) |
function calendar.leapDays(y) |
||
local info = calendar.lunarInfo[y - 1900] |
|||
if not info then return 0 end |
|||
if calendar.leapMonth(y) ~= 0 then |
if calendar.leapMonth(y) ~= 0 then |
||
return band( |
return band(info, 0x10000) ~= 0 and 30 or 29 |
||
end |
end |
||
return 0 |
return 0 |
2025年1月7日 (二) 16:12的版本
local p = {}
-- 位运算模拟函数
local function band(a, b)
a = tonumber(a) or 0
b = tonumber(b) or 0
local result = 0
local bitval = 1
-- 转换为正整数处理
a = math.floor(math.abs(a))
b = math.floor(math.abs(b))
while a > 0 or b > 0 do
if a % 2 == 1 and b % 2 == 1 then
result = result + bitval
end
bitval = bitval * 2
a = math.floor(a/2)
b = math.floor(b/2)
end
return result
end
-- 农历数据表
local calendar = {
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 },
Gan = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" },
Zhi = { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" },
Animals = { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" },
nStr1 = { "日", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" },
nStr2 = { "初", "十", "廿", "卅" },
nStr3 = { "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊" }
}
-- 核心转换函数
function calendar.solar2lunar(y, m, d)
-- 边界检查
if y < 1900 or y > 2100 then return nil end
if y == 1900 and m == 1 and d < 31 then return nil end
-- 计算距离1900年1月31日的总天数
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
-- 计算农历年
while i < 2101 and offset > 0 do
temp = calendar.lYearDays(i)
offset = offset - temp
i = i + 1
end
if offset < 0 then
offset = offset + temp
i = i - 1
end
local year = i
leap = calendar.leapMonth(year)
local isLeap = false
-- 计算月
i = 1
while i < 13 and offset > 0 do
if leap > 0 and i == (leap + 1) and isLeap == false then
i = i - 1
isLeap = true
temp = calendar.leapDays(year)
else
temp = calendar.monthDays(year, i)
end
if isLeap == true and i == (leap + 1) then
isLeap = false
end
offset = offset - temp
i = i + 1
end
if offset == 0 and leap > 0 and i == leap + 1 then
if isLeap then
isLeap = false
else
isLeap = true
i = i - 1
end
end
if offset < 0 then
offset = offset + temp
i = i - 1
end
local month = i
local day = offset + 1
return {
lYear = year,
lMonth = month,
lDay = day,
isLeap = isLeap
}
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
result = result .. calendar.nStr2[4] .. calendar.nStr1[lunar.lDay - 30]
end
return result
end
return p