Module:HebrewDate

.mw-parser-output .documentation,.mw-parser-output .documentation-metadata{border:1px solid var(--border-color-base,#a2a9b1);background-color:#ecfcf4;color:inhe

Module:HebrewDate
local p = {}

-- ==========================================================
-- 1. CORE CALENDAR MATH
-- ==========================================================
local hebrew_epoch = -1373427

local function div(a, b) return math.floor(a / b) end
local function mod(a, b) return a - math.floor(a / b) * b end

local function elapsed_days(year)
    local months = div(235 * year - 234, 19)
    local parts = 12084 + 13753 * months
    local day = 29 * months + div(parts, 25920)
    -- Dehuiyot: adjust if molad falls on Sunday, Wednesday, or Friday
    if mod(3 * (day + 1), 7) < 3 then
        return day + 1
    end
    return day
end

local function new_year_delay(year)
    local n0 = elapsed_days(year - 1)
    local n1 = elapsed_days(year)
    local n2 = elapsed_days(year + 1)
    if (n2 - n1) == 356 then return 2 end
    if (n1 - n0) == 382 then return 1 end
    return 0
end

local function hebrew_new_year(year)
    return hebrew_epoch + elapsed_days(year) + new_year_delay(year)
end

local function is_greg_leap(y)
    return (mod(y, 4) == 0 and mod(y, 100) ~= 0) or (mod(y, 400) == 0)
end

local function gregorian_to_fixed(y, m, d)
    local days = 365 * (y - 1) + div(y - 1, 4) - div(y - 1, 100) + div(y - 1, 400)
    local month_days = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}
    days = days + month_days[m]
    if m > 2 and is_greg_leap(y) then days = days + 1 end
    return days + d
end

local function get_month_length(month, is_leap, year_len)
    if month == 13 then return is_leap and 29 or 0 end
    if month == 12 then return is_leap and 30 or 29 end
    if month == 2 or month == 4 or month == 6 or month == 10 then return 29 end
    if month == 8 then return (year_len == 355 or year_len == 385) and 30 or 29 end
    if month == 9 then return (year_len == 353 or year_len == 383) and 29 or 30 end
    return 30
end

-- ==========================================================
-- 2. MAIN EXECUTION
-- ==========================================================
function p.main(frame)
    -- Get current UTC time
    local current_time = os.time()
    local t = os.date("!*t", current_time)
    
    -- If it is 6:00 PM (18:00) UTC or later, roll forward to the next day
    if t.hour >= 18 then
        current_time = current_time + 86400
        t = os.date("!*t", current_time)
    end
    
    -- Convert Gregorian date to Rata Die (Fixed days since 1 CE)
    local rd = gregorian_to_fixed(t.year, t.month, t.day)
    
    -- Find the corresponding Hebrew Year
    local appx = 1 + div((rd - hebrew_epoch) * 98496, 35975351)
    local Y = appx - 1
    while hebrew_new_year(Y + 1) <= rd do
        Y = Y + 1
    end
    
    -- Determine year characteristics
    local is_leap = mod(1 + 7 * Y, 19) < 7
    local year_len = hebrew_new_year(Y + 1) - hebrew_new_year(Y)
    
    -- Iterate through the months to find the current month and day
    local seq = {7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6}
    local days_remaining = rd - hebrew_new_year(Y)
    local H_month = 7
    
    for _, m in ipairs(seq) do
        local m_len = get_month_length(m, is_leap, year_len)
        if m_len > 0 then
            if days_remaining < m_len then
                H_month = m
                break
            else
                days_remaining = days_remaining - m_len
            end
        end
    end
    
    local H_day = days_remaining + 1
    
    -- Map month number to text
    local month_names = {
        [1] = "Nisan", [2] = "Iyyar", [3] = "Sivan", [4] = "Tammuz",
        [5] = "Av", [6] = "Elul", [7] = "Tishri", [8] = "Marheshvan",
        [9] = "Kislev", [10] = "Tevet", [11] = "Shevat", [12] = "Adar", [13] = "Adar II"
    }
    
    local date_no_year = H_day .. " " .. month_names[H_month]
    local date_with_year = date_no_year .. " " .. Y
    
    return "[[" .. date_no_year .. "|" .. date_with_year .. "]]"
end

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.