跳转到内容

模組:沙盒/Willy1018/ChineseCalendar

维基百科,自由的百科全书

这是本页的一个历史版本,由Willy1018留言 | 贡献2025年4月30日 (三) 19:39编辑。这可能和当前版本存在着巨大的差异。

local p = {}

-- 天干與地支
local gan = {'甲','乙','丙','丁','戊','己','庚','辛','壬','癸'}
local zhi = {'子','丑','寅','卯','辰','巳','午','未','申','酉','戌','亥'}

-- 傳統月份名稱
local monthNames = {'正','二','三','四','五','六','七','八','九','十','冬','臘'}

-- 傳統日期名稱(1=初一, 2=初二, ..., 30=三十)
local dayNames = {
    '初一','初二','初三','初四','初五','初六','初七','初八','初九','初十',
    '十一','十二','十三','十四','十五','十六','十七','十八','十九','二十',
    '廿一','廿二','廿三','廿四','廿五','廿六','廿七','廿八','廿九','三十'
}

-- 計算公曆年份對應的農曆干支年份
function p.getGanZhiYear(year)
    local offset = (year - 1984) % 60
    return gan[(offset % 10) + 1] .. zhi[(offset % 12) + 1]
end

-- 判斷是否閏年
function p.isLeapYear(year)
    return (year % 4 == 0 and year % 100 ~= 0) or (year % 400 == 0)
end

-- 計算公曆日期轉農曆日期
function p.gregorianToLunar(year, month, day)
    -- 農曆的基準年份和其對應的公曆日期(設為基準點,例如某個已知農曆年份的公曆日期)
    local baseYear = 2023
    local baseDate = {year = 2023, month = 1, day = 22}  -- 這裡應使用已知的農曆基準日期
    local lunarBase = {year = 2023, month = 1, day = 1, isLeap = false}

    -- 計算基準日期距離輸入日期的天數差(可以用簡單的日差算法)
    local dayDiff = p.dateDifference(baseDate, {year = year, month = month, day = day})

    -- 根據日數差推算農曆日期
    local lunarYear = lunarBase.year
    local lunarMonth = lunarBase.month
    local lunarDay = lunarBase.day + dayDiff
    local isLeapMonth = lunarBase.isLeap

    -- 根據農曆規則調整月份和年份
    while lunarDay > p.getLunarMonthDays(lunarYear, lunarMonth, isLeapMonth) do
        lunarDay = lunarDay - p.getLunarMonthDays(lunarYear, lunarMonth, isLeapMonth)
        if isLeapMonth then
            isLeapMonth = false
        elseif p.isLeapMonth(lunarYear, lunarMonth) then
            isLeapMonth = true
        else
            lunarMonth = lunarMonth + 1
            if lunarMonth > 12 then
                lunarMonth = 1
                lunarYear = lunarYear + 1
            end
        end
    end

    return {
        year = lunarYear,
        month = lunarMonth,
        day = lunarDay,
        isLeap = isLeapMonth
    }
end

-- 農曆月份的天數(假設邏輯,29或30天)
function p.getLunarMonthDays(year, month, isLeap)
    -- 模擬月份天數:實際需要根據正確農曆規則計算
    return (month % 2 == 0) and 29 or 30
end

-- 判斷農曆某年某月是否閏月(假設邏輯)
function p.isLeapMonth(year, month)
    -- 根據正確農曆規則判斷閏月:此處需要替換為專業算法
    return month == 4 -- 假設某年農曆的閏月是四月
end

-- 計算兩個日期的天數差
function p.dateDifference(date1, date2)
    -- 假設date1和date2為表:{year=2023, month=1, day=22}
    local days = 0
    -- 計算年份差距的天數
    for y = date1.year, date2.year - 1 do
        days = days + (p.isLeapYear(y) and 366 or 365)
    end
    -- 計算月份和日期差距的天數
    days = days + p.getDaysInYear(date2.year, date2.month, date2.day) - p.getDaysInYear(date1.year, date1.month, date1.day)
    return days
end

-- 計算某日期是當年的第幾天
function p.getDaysInYear(year, month, day)
    local days = day
    local daysInMonths = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    if p.isLeapYear(year) then
        daysInMonths[2] = 29 -- 閏年二月有29天
    end
    for i = 1, month - 1 do
        days = days + daysInMonths[i]
    end
    return days
end

-- 主函數:輸入年月日 → 回傳農曆日期字符串
function p.getLunarString(frame)
    local y = tonumber(frame.args.year)
    local m = tonumber(frame.args.month)
    local d = tonumber(frame.args.day)

    if not (y and m and d) then
        return "錯誤:請提供 year、month、day"
    end

    local lunar = p.gregorianToLunar(y, m, d)
    local gz = p.getGanZhiYear(lunar.year)
    local monthStr = (lunar.isLeap and '閏' or '') .. monthNames[lunar.month] .. '月'
    local dayStr = dayNames[lunar.day]

    return '今日是' .. gz .. '年' .. monthStr .. dayStr
end

-- 返回表
return p