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

模块:Chinese calendar:修订间差异

来自奇葩栖息地
添加的内容 删除的内容
(//Edit via InPageEdit)
无编辑摘要
第22行: 第22行:
-- 农历数据 (1900-2100)
-- 农历数据 (1900-2100)
local LUNAR_INFO = {
local LUNAR_INFO = {
0x04bd8,
0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
0x04ae0,
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,
0x0a570,
0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
0x054d5,
0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,
0x0d260,
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,
0x0d950,
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0,
0x16554,
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,
0x056a0,
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
0x09ad0,
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,
0x055d2, --1900-1909
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,
0x04ae0,
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,
0x0a5b6,
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,
0x0a4d0,
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,
0x0d250,
0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,
0x1d255,
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0
0x0b540,
}
0x0d6a0,
0x0ada2,
0x095b0,
0x14977, --1910-1919
0x04970,
0x0a4b0,
0x0b4b5,
0x06a50,
0x06d40,
0x1ab54,
0x02b60,
0x09570,
0x052f2,
0x04970, --1920-1929
0x06566,
0x0d4a0,
0x0ea50,
0x06e95,
0x05ad0,
0x02b60,
0x186e3,
0x092e0,
0x1c8d7,
0x0c950, --1930-1939
0x0d4a0,
0x1d8a6,
0x0b550,
0x056a0,
0x1a5b4,
0x025d0,
0x092d0,
0x0d2b2,
0x0a950,
0x0b557, --1940-1949
0x06ca0,
0x0b550,
0x15355,
0x04da0,
0x0a5b0,
0x14573,
0x052b0,
0x0a9a8,
0x0e950,
0x06aa0, --1950-1959
0x0aea6,
0x0ab50,
0x04b60,
0x0aae4,
0x0a570,
0x05260,
0x0f263,
0x0d950,
0x05b57,
0x056a0, --1960-1969
0x096d0,
0x04dd5,
0x04ad0,
0x0a4d0,
0x0d4d4,
0x0d250,
0x0d558,
0x0b540,
0x0b6a0,
0x195a6, --1970-1979
0x095b0,
0x049b0,
0x0a974,
0x0a4b0,
0x0b27a,
0x06a50,
0x06d40,
0x0af46,
0x0ab60,
0x09570, --1980-1989
0x04af5,
0x04970,
0x064b0,
0x074a3,
0x0ea50,
0x06b58,
0x055c0,
0x0ab60,
0x096d5,
0x092e0, --1990-1999
0x0c960,
0x0d954,
0x0d4a0,
0x0da50,
0x07552,
0x056a0,
0x0abb7,
0x025d0,
0x092d0,
0x0cab5, --2000-2009
0x0a950,
0x0b4a0,
0x0baa4,
0x0ad50,
0x055d9,
0x04ba0,
0x0a5b0,
0x15176,
0x052b0,
0x0a930, --2010-2019
0x07954,
0x06aa0,
0x0ad50,
0x05b52,
0x04b60,
0x0a6e6,
0x0a4e0,
0x0d260,
0x0ea65,
0x0d530, --2020-2029
0x05aa0,
0x076a3,
0x096d0,
0x04afb,
0x04ad0,
0x0a4d0,
0x1d0b6,
0x0d250,
0x0d520,
0x0dd45, --2030-2039
0x0b5a0,
0x056d0,
0x055b2,
0x049b0,
0x0a577,
0x0a4b0,
0x0aa50,
0x1b255,
0x06d20,
0x0ada0, --2040-2049
0x14b63,
0x09370,
0x049f8,
0x04970,
0x064b0,
0x168a6,
0x0ea50,
0x06b20,
0x1a6c4,
0x0aae0, --2050-2059
0x0a2e0,
0x0d2e3,
0x0c960,
0x0d557,
0x0d4a0,
0x0da50,
0x05d55,
0x056a0,
0x0a6d0,
0x055d4, --2060-2069
0x052d0,
0x0a9b8,
0x0a950,
0x0b4a0,
0x0b6a6,
0x0ad50,
0x055a0,
0x0aba4,
0x0a5b0,
0x052b0, --2070-2079
0x0b273,
0x06930,
0x07337,
0x06aa0,
0x0ad50,
0x14b55,
0x04b60,
0x0a570,
0x054e4,
0x0d160, --2080-2089
0x0e968,
0x0d520,
0x0daa0,
0x16aa6,
0x056d0,
0x04ae0,
0x0a9d4,
0x0a2d0,
0x0d150,
0x0f252, --2090-2099
0x0d520,
} --2100


-- 检查日期是否合法
-- 检查日期是否合法
第62行: 第248行:
end
end


local function leapMonth(y)
-- 获取某年农历数据中的月份大小信息
return extract(LUNAR_INFO[y - 1900], 0, 4)
local function getMonthSizes(lunarCode)
local monthSizes = {}
for i = 1, 12 do
monthSizes[i] = extract(lunarCode, 12 - i, 1) == 1 and 30 or 29
end
return monthSizes
end
end


local function leapDays(y)
-- 获取闰月信息
if leapMonth(y) > 0 then
local function getLeapMonth(lunarCode)
return extract(lunarCode, 12, 4)
return extract(LUNAR_INFO[y - 1900], 16, 1) > 0 and 30 or 29
end
return 0
end
end


local function monthDays(y, m)
-- 获取春节日期
if m > 12 or m < 1 then return -1 end
local function getSpringFestival(lunarCode)
local month = extract(lunarCode, 16, 2) + 1
local bit = extract(LUNAR_INFO[y - 1900], 16 - m, 1)
return bit > 0 and 30 or 29
local day = extract(lunarCode, 18, 6)
if day > 31 then
day = day - 31
month = month + 1
end
return month, day
end
end


local function lYearDays(y)
-- 计算农历日期
local sum = 348
local function calculateLunarDate(yearCode, year, month, day)
local info = LUNAR_INFO[y - 1900]
-- 获取春节日期
for i = 15, 4, -1 do
local sfMonth, sfDay = getSpringFestival(yearCode)
local bit = extract(info, i, 1)

if bit > 0 then
-- 计算目标日期和春节的天数差
sum = sum + 1
local targetDayOfYear = getDayOfYear(year, month, day)
local springFestivalDayOfYear = getDayOfYear(year, sfMonth, sfDay)
local dayDiff = targetDayOfYear - springFestivalDayOfYear

-- 如果在春节前,使用上一年的农历数据
if dayDiff < 0 then
local prevYear = year - 1
local prevYearCode = LUNAR_INFO[prevYear - 1900 + 1]
-- 获取上一年的月份数据
local prevMonthSizes = getMonthSizes(prevYearCode)
local prevLeapMonth = getLeapMonth(prevYearCode)

-- 计算距离上一年最后一天的天数
local daysFromPrevYearEnd = targetDayOfYear
local monthCount = 12
local currMonth = monthCount
local days = daysFromPrevYearEnd

-- 从上一年最后一个月开始往前算
while currMonth > 0 and days > 0 do
if days <= prevMonthSizes[currMonth] then
return currMonth, days, currMonth == prevLeapMonth, prevYear
end
days = days - prevMonthSizes[currMonth]
currMonth = currMonth - 1
end
end
end
end
return sum + leapDays(y)

-- 获取当年农历月份大小
local monthSizes = getMonthSizes(yearCode)
local leapMonth = getLeapMonth(yearCode)

-- 计算农历月份和日期
local days = dayDiff
local lunarMonth = 1
local isLeapMonth = false

while days >= monthSizes[lunarMonth] do
days = days - monthSizes[lunarMonth]

if lunarMonth == leapMonth then
if not isLeapMonth then
isLeapMonth = true
if days >= monthSizes[lunarMonth] then
days = days - monthSizes[lunarMonth]
lunarMonth = lunarMonth + 1
end
else
lunarMonth = lunarMonth + 1
isLeapMonth = false
end
else
lunarMonth = lunarMonth + 1
end

if lunarMonth > 12 then
return 1, days + 1, false, year + 1
end
end

return lunarMonth, days + 1, isLeapMonth, year
end
end


第159行: 第280行:
function p.toLunar(frame)
function p.toLunar(frame)
local date = frame.args[1]
local date = frame.args[1]
local showSolarTerm = frame.args.showSolarTerm
if type(showSolarTerm) == "string" then
showSolarTerm = (showSolarTerm == "true" or showSolarTerm == "1")
end


-- 输入格式验证
-- 输入格式验证
第184行: 第301行:
end
end


-- 输出日期
-- 计算总天数
local yearCode = LUNAR_INFO[year - 1900 + 1]
local offset = getDayOfYear(year, month, day)
local temp = 0
local lunarMonth, lunarDay, isLeapMonth, lunarYear = calculateLunarDate(yearCode, year, month, day)

-- 计算农历年份
for i = 1900, year - 1 do
temp = lYearDays(i)
offset = offset + temp
end

-- 计算农历月份和日期
local lunarYear = year
local lunarMonth = 1
local lunarDay = 1

temp = lYearDays(lunarYear)
while offset > temp do
offset = offset - temp
lunarYear = lunarYear + 1
temp = lYearDays(lunarYear)
end

temp = monthDays(lunarYear, lunarMonth)
while offset > temp do
offset = offset - temp
lunarMonth = lunarMonth + 1
if lunarMonth > 12 then
lunarMonth = 1
lunarYear = lunarYear + 1
end
temp = monthDays(lunarYear, lunarMonth)
end

lunarDay = offset

-- 生成输出
local stemIndex = (lunarYear - 4) % 10
local stemIndex = (lunarYear - 4) % 10
local branchIndex = (lunarYear - 4) % 12
local branchIndex = (lunarYear - 4) % 12
local result = HEAVENLY_STEMS[stemIndex + 1] .. EARTHLY_BRANCHES[branchIndex + 1] .. '年'
local result = HEAVENLY_STEMS[stemIndex + 1] .. EARTHLY_BRANCHES[branchIndex + 1] .. '年'

local isLeapMonth = false
local lm = leapMonth(lunarYear)
if lm > 0 and lunarMonth > lm then
lunarMonth = lunarMonth - 1
if lunarMonth == lm then
isLeapMonth = true
end
end

if isLeapMonth then
if isLeapMonth then
result = result .. '闰'
result = result .. '闰'

2025年1月1日 (三) 10:30的版本

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

local function extract(num, pos, len)
    local shifted = math.floor(num / (2 ^ pos))
    local result = shifted % (2 ^ len)
    return result
end

-- 天干
local HEAVENLY_STEMS = { '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸' }
-- 地支
local EARTHLY_BRANCHES = { '子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥' }
-- 月份
local LUNAR_MONTHS = { '正', '二', '三', '四', '五', '六', '七', '八', '九', '十', '冬', '腊' }
-- 日期
local LUNAR_DAYS = {
    '初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十',
    '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十',
    '廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十'
}

-- 农历数据 (1900-2100)
local LUNAR_INFO = {
    0x04bd8,
    0x04ae0,
    0x0a570,
    0x054d5,
    0x0d260,
    0x0d950,
    0x16554,
    0x056a0,
    0x09ad0,
    0x055d2,     --1900-1909
    0x04ae0,
    0x0a5b6,
    0x0a4d0,
    0x0d250,
    0x1d255,
    0x0b540,
    0x0d6a0,
    0x0ada2,
    0x095b0,
    0x14977,     --1910-1919
    0x04970,
    0x0a4b0,
    0x0b4b5,
    0x06a50,
    0x06d40,
    0x1ab54,
    0x02b60,
    0x09570,
    0x052f2,
    0x04970,     --1920-1929
    0x06566,
    0x0d4a0,
    0x0ea50,
    0x06e95,
    0x05ad0,
    0x02b60,
    0x186e3,
    0x092e0,
    0x1c8d7,
    0x0c950,     --1930-1939
    0x0d4a0,
    0x1d8a6,
    0x0b550,
    0x056a0,
    0x1a5b4,
    0x025d0,
    0x092d0,
    0x0d2b2,
    0x0a950,
    0x0b557,     --1940-1949
    0x06ca0,
    0x0b550,
    0x15355,
    0x04da0,
    0x0a5b0,
    0x14573,
    0x052b0,
    0x0a9a8,
    0x0e950,
    0x06aa0,     --1950-1959
    0x0aea6,
    0x0ab50,
    0x04b60,
    0x0aae4,
    0x0a570,
    0x05260,
    0x0f263,
    0x0d950,
    0x05b57,
    0x056a0,     --1960-1969
    0x096d0,
    0x04dd5,
    0x04ad0,
    0x0a4d0,
    0x0d4d4,
    0x0d250,
    0x0d558,
    0x0b540,
    0x0b6a0,
    0x195a6,     --1970-1979
    0x095b0,
    0x049b0,
    0x0a974,
    0x0a4b0,
    0x0b27a,
    0x06a50,
    0x06d40,
    0x0af46,
    0x0ab60,
    0x09570,     --1980-1989
    0x04af5,
    0x04970,
    0x064b0,
    0x074a3,
    0x0ea50,
    0x06b58,
    0x055c0,
    0x0ab60,
    0x096d5,
    0x092e0,     --1990-1999
    0x0c960,
    0x0d954,
    0x0d4a0,
    0x0da50,
    0x07552,
    0x056a0,
    0x0abb7,
    0x025d0,
    0x092d0,
    0x0cab5,     --2000-2009
    0x0a950,
    0x0b4a0,
    0x0baa4,
    0x0ad50,
    0x055d9,
    0x04ba0,
    0x0a5b0,
    0x15176,
    0x052b0,
    0x0a930,     --2010-2019
    0x07954,
    0x06aa0,
    0x0ad50,
    0x05b52,
    0x04b60,
    0x0a6e6,
    0x0a4e0,
    0x0d260,
    0x0ea65,
    0x0d530,     --2020-2029
    0x05aa0,
    0x076a3,
    0x096d0,
    0x04afb,
    0x04ad0,
    0x0a4d0,
    0x1d0b6,
    0x0d250,
    0x0d520,
    0x0dd45,     --2030-2039
    0x0b5a0,
    0x056d0,
    0x055b2,
    0x049b0,
    0x0a577,
    0x0a4b0,
    0x0aa50,
    0x1b255,
    0x06d20,
    0x0ada0,     --2040-2049
    0x14b63,
    0x09370,
    0x049f8,
    0x04970,
    0x064b0,
    0x168a6,
    0x0ea50,
    0x06b20,
    0x1a6c4,
    0x0aae0,     --2050-2059
    0x0a2e0,
    0x0d2e3,
    0x0c960,
    0x0d557,
    0x0d4a0,
    0x0da50,
    0x05d55,
    0x056a0,
    0x0a6d0,
    0x055d4,     --2060-2069
    0x052d0,
    0x0a9b8,
    0x0a950,
    0x0b4a0,
    0x0b6a6,
    0x0ad50,
    0x055a0,
    0x0aba4,
    0x0a5b0,
    0x052b0,     --2070-2079
    0x0b273,
    0x06930,
    0x07337,
    0x06aa0,
    0x0ad50,
    0x14b55,
    0x04b60,
    0x0a570,
    0x054e4,
    0x0d160,     --2080-2089
    0x0e968,
    0x0d520,
    0x0daa0,
    0x16aa6,
    0x056d0,
    0x04ae0,
    0x0a9d4,
    0x0a2d0,
    0x0d150,
    0x0f252,     --2090-2099
    0x0d520,
}                --2100

-- 检查日期是否合法
local function isValidDate(year, month, day)
    local days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    if (year % 4 == 0 and year % 100 ~= 0) or (year % 400 == 0) then
        days[2] = 29
    end
    return day <= days[month]
end

-- 计算指定公历日期是一年中的第几天
local function getDayOfYear(year, month, day)
    local days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    if (year % 4 == 0 and year % 100 ~= 0) or (year % 400 == 0) then
        days[2] = 29
    end

    local dayOfYear = day
    for i = 1, month - 1 do
        dayOfYear = dayOfYear + days[i]
    end
    return dayOfYear
end

local function leapMonth(y)
    return extract(LUNAR_INFO[y - 1900], 0, 4)
end

local function leapDays(y)
    if leapMonth(y) > 0 then
        return extract(LUNAR_INFO[y - 1900], 16, 1) > 0 and 30 or 29
    end
    return 0
end

local function monthDays(y, m)
    if m > 12 or m < 1 then return -1 end
    local bit = extract(LUNAR_INFO[y - 1900], 16 - m, 1)
    return bit > 0 and 30 or 29
end

local function lYearDays(y)
    local sum = 348
    local info = LUNAR_INFO[y - 1900]
    for i = 15, 4, -1 do
        local bit = extract(info, i, 1)
        if bit > 0 then
            sum = sum + 1
        end
    end
    return sum + leapDays(y)
end

-- 将公历日期转换为农历日期
function p.toLunar(frame)
    local date = frame.args[1]

    -- 输入格式验证
    if not date:match('^%d%d%d%d%-%d%d%-%d%d$') then
        return '错误:日期格式无效,请使用YYYY-MM-DD格式'
    end

    local year = tonumber(date:sub(1, 4))
    local month = tonumber(date:sub(6, 7))
    local day = tonumber(date:sub(9, 10))

    -- 输入日期范围验证
    if year < 1900 or year > 2100 then
        return '错误:年份超出范围(1900-2100)'
    end
    if month < 1 or month > 12 then
        return '错误:月份无效'
    end
    if not isValidDate(year, month, day) then
        return '错误:日期无效'
    end

    -- 计算总天数
    local offset = getDayOfYear(year, month, day)
    local temp = 0

    -- 计算农历年份
    for i = 1900, year - 1 do
        temp = lYearDays(i)
        offset = offset + temp
    end

    -- 计算农历月份和日期
    local lunarYear = year
    local lunarMonth = 1
    local lunarDay = 1

    temp = lYearDays(lunarYear)
    while offset > temp do
        offset = offset - temp
        lunarYear = lunarYear + 1
        temp = lYearDays(lunarYear)
    end

    temp = monthDays(lunarYear, lunarMonth)
    while offset > temp do
        offset = offset - temp
        lunarMonth = lunarMonth + 1
        if lunarMonth > 12 then
            lunarMonth = 1
            lunarYear = lunarYear + 1
        end
        temp = monthDays(lunarYear, lunarMonth)
    end

    lunarDay = offset

    -- 生成输出
    local stemIndex = (lunarYear - 4) % 10
    local branchIndex = (lunarYear - 4) % 12
    local result = HEAVENLY_STEMS[stemIndex + 1] .. EARTHLY_BRANCHES[branchIndex + 1] .. '年'

    local isLeapMonth = false
    local lm = leapMonth(lunarYear)
    if lm > 0 and lunarMonth > lm then
        lunarMonth = lunarMonth - 1
        if lunarMonth == lm then
            isLeapMonth = true
        end
    end

    if isLeapMonth then
        result = result .. '闰'
    end
    result = result .. LUNAR_MONTHS[lunarMonth] .. '月' .. LUNAR_DAYS[lunarDay]

    return result
end

return p