Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

// request.cf · coarse context

A page that knows where it met you.

Only coarse request metadata is shown. This demo does not display or persist visitor IP addresses.

Country
US
Cloudflare location
CMH
Connection
HTTP/2
Language
Not provided

Ray ID: a231dba28f56a0d6

Jump to content

Module:HebrewDate

From Wikipedia, the free encyclopedia
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