模組:沙盒/Willy1018/ChineseCalendar
外观
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