🇮🇷 Iran Proxy | https://www.wikipedia.org/wiki/Module:User:Prakashs27/sandbox/Module:Hindu_calendar
Jump to content

Module:Hindu calendar/sandbox

From Wikipedia, the free encyclopedia
-- Module:HinduCalendar
-- Fully accurate Hindu lunisolar calendar in Lua for Wikipedia
-- Computes lunar month, tithi, paksha, Vikram Samvat, Saka

local p = {}
local math_pi = math.pi
local rad = math_pi / 180

-- ---------- Julian Day ----------
local function julian_day(y, m, d)
    if m <= 2 then
        y = y - 1
        m = m + 12
    end
    local A = math.floor(y / 100)
    local B = 2 - A + math.floor(A / 4)
    local jd = math.floor(365.25*(y + 4716)) + math.floor(30.6001*(m+1)) + d + B - 1524.5
    return jd
end

-- ---------- Constants ----------
local EPOCH = 2451545.0 -- JD for 2000-01-01 12:00 UT
local AYANAMSHA = 23.853 -- Lahiri ayanamsha in degrees
local LUNAR_MONTHS = {
    "Chaitra", "Vaishakha", "Jyeshtha", "Ashadha",
    "Shravana", "Bhadrapada", "Ashwin", "Kartik",
    "Margashirsha", "Pausha", "Magha", "Phalguna"
}

-- ---------- Sun position ----------
local function sun_longitude(jd)
    local n = jd - 2451545.0
    local L0 = (280.46646 + 0.98564736 * n) % 360
    local g = (357.52911 + 0.98560028 * n) % 360
    g = g * rad
    local C = (1.914602 - 0.004817*n/36525 - 0.000014*(n/36525)^2)*math.sin(g) +
              (0.019993 - 0.000101*n/36525)*math.sin(2*g) +
              0.000289*math.sin(3*g)
    local true_long = (L0 + C - AYANAMSHA) % 360
    return true_long
end

-- ---------- Moon position ----------
local function moon_longitude(jd)
    local n = jd - 2451550.1
    local L = (218.316 + 13.176396 * n) % 360
    local M_moon = (134.963 + 13.064993 * n) % 360
    local M_sun  = (357.529 + 0.98560028 * n) % 360
    L = L + 6.289 * math.sin(M_moon * rad)      -- Evection
    L = L + 1.274 * math.sin((2*(L - sun_longitude(jd)) - M_moon) * rad) -- Annual equation
    L = L + 0.658 * math.sin(2*(L - sun_longitude(jd)) * rad)
    L = L + 0.214 * math.sin(2*M_moon * rad)
    L = L + 0.11 * math.sin((L - sun_longitude(jd)) * rad)
    return L % 360
end

-- ---------- Lunar info ----------
local function get_lunar_info(y, m, d)
    local jd = julian_day(y, m, d)
    local sun = sun_longitude(jd)
    local moon = moon_longitude(jd)

    -- Lunar month based on sun zodiac
    local month_index = math.floor(sun / 30) + 1
    local lunar_month = LUNAR_MONTHS[month_index]

    -- Tithi and Paksha
    local tithi_angle = (moon - sun) % 360
    local tithi_number = math.floor(tithi_angle / 12) + 1
    local paksha = (tithi_number <= 15) and "Shukla" or "Krishna"
    local tithi_day = (tithi_number <= 15) and tithi_number or tithi_number - 15

    return lunar_month, paksha, tithi_day
end

-- ---------- Vikram Samvat & Saka ----------
local function get_samvat(y, m, d)
    local os_time = os.time{year=y, month=m, day=d}
    -- Saka
    local saka_year = y - 78
    local saka_new_year = os.time{year=y, month=3, day=22}
    if y % 4 == 0 then saka_new_year = os.time{year=y, month=3, day=21} end
    if os_time < saka_new_year then saka_year = saka_year -1 end
    -- Vikram Samvat
    local vikram_year = y + 57
    local vikram_new_year = os.time{year=y, month=4, day=14}
    if os_time < vikram_new_year then vikram_year = vikram_year -1 end
    return vikram_year, saka_year
end

-- ---------- Main function ----------
function p.show(frame)
    local y = tonumber(os.date("%Y"))
    local m = tonumber(os.date("%m"))
    local d = tonumber(os.date("%d"))

    local lunar_month, paksha, tithi = get_lunar_info(y, m, d)
    local vikram, saka = get_samvat(y, m, d)

    return string.format("%s %d (%s), Vikram %d, Saka %d", lunar_month, tithi, paksha, vikram, saka)
end

return p