模块:ASADCalendarConvertion

来自图琴维基
Kufscrow讨论 | 贡献2025年6月6日 (五) 07:37的版本 (已保护“模块:ASADCalendarConvertion”:​日历转换函数([编辑=仅允许管理员](无限期)[移动=仅允许管理员](无限期)))
跳到导航 跳到搜索

此模块的文档可以在模块:ASADCalendarConvertion/doc创建

local p = {}

-- Julian Day Number conversion
function to_jdn(year, month, day)
    local a = math.floor((14 - month) / 12)
    local y = year + 4800 - a
    local m = month + 12 * a - 3
    return day + math.floor((153 * m + 2) / 5) + 365 * y + math.floor(y / 4) - math.floor(y / 100) + math.floor(y / 400) - 32045
end

function from_jdn(jdn)
    local f = jdn + 1401 + math.floor(math.floor((4 * jdn + 274277) / 146097) * 3 / 4) - 38
    local e = 4 * f + 3
    local g = math.floor((e % 1461) / 4)
    local h = 5 * g + 2
    local day = math.floor((h % 153) / 5) + 1
    local month = (math.floor(h / 153) + 2) % 12 + 1
    local year = math.floor(e / 1461) - 4716 + math.floor((14 - month) / 12)
    return year, month, day
end

-- Julian Day Equivalent in Turchine Standard Calendar conversion
function to_tdn(year, month, day)
    local y = (year + 2000) * 365 + math.floor((year - 1) / 4) + 501
    local mod = year % 4
    local leap_adjust = 6 - math.floor((mod + 3) / 4)
    local m = 30 * (month - 1) + math.floor(month / 7) * leap_adjust
    local d = day - 1
    return y + m + d
end

function from_tdn(D)
    local P = 1461
    local q = math.floor(D / P)
    local R = D % P
    local index = math.floor(4 * R / P)
    local base_days = 365 * index + math.floor((index + 3) / 4)
    local E = R - base_days
    local year = 4 * q + index - 2000
    local leap = 1 - (index > 0 and 1 or 0)
    local L = 35 + leap
    local in_first_5 = E < 150
    local in_june = E >= 150 and E < 150 + L
    local in_after_june = E >= 150 + L

    local month, day
    if in_first_5 then
        month = math.floor(E / 30) + 1
        day = (E % 30) + 1
    elseif in_june then
        month = 6
        day = E - 150 + 1
    else
        local E_after = E - 150 - L
        month = 7 + math.floor(E_after / 30)
        day = (E_after % 30) + 1
    end

    return year, month, day
end

-- Calendar Day Constants
local AD_st = to_jdn(2271, 8, 2)
local AS_st = to_tdn(1372, 6, 18)

-- Format helper with AD/AS label
local function format_date(year, month, day, label)
    return string.format("%d.%d.%d%s", year, month, day, label)
end

-- Main conversions with formatted output + label
function p.AD_to_AS(frame)
    local year = tonumber(frame.args[1])
    local month = tonumber(frame.args[2])
    local day = tonumber(frame.args[3])
    local y, m, d = from_tdn(to_jdn(year, month, day) - AD_st + AS_st)
    return format_date(y, m, d, "AS")
end

function p.AS_to_AD(frame)
    local year = tonumber(frame.args[1])
    local month = tonumber(frame.args[2])
    local day = tonumber(frame.args[3])
    local y, m, d = from_jdn(to_tdn(year, month, day) - AS_st + AD_st)
    return format_date(y, m, d, "AD")
end

return p