Modul':Päiväine nouzeb

Рувики-späi

Selle mooduli dokumentatsiooni saab kirjutada asukohta Modul':Päiväine nouzeb/doc.

local p = {}

-- Вспомогательная функция для расчета Юлианской даты
local function calculateJulianDate(year, month, day)
    if month <= 2 then
        year = year - 1
        month = month + 12
    end
    local A = math.floor(year / 100)
    local B = 2 - A + math.floor(A / 4)
    return math.floor(365.25 * (year + 4716)) + math.floor(30.6001 * (month + 1)) + day + B - 1524.5
end

-- Основная функция для вычисления восхода и заката
local function calculateSunTimesForDate(jd, latitude, longitude)
    local rad = math.pi / 180
    local sin, cos, asin, acos = math.sin, math.cos, math.asin, math.acos

    -- Средняя аномалия
    local n = jd - 2451545.0
    local L = (280.46 + 0.9856474 * n) % 360
    local g = (357.528 + 0.9856003 * n) % 360
    local lambda = L + 1.915 * sin(g * rad) + 0.02 * sin(2 * g * rad)
    local epsilon = 23.439 - 0.0000004 * n

    local declination = asin(sin(epsilon * rad) * sin(lambda * rad)) / rad
    local time_offset = -longitude / 15

    local cosH = (cos(90.833 * rad) - sin(latitude * rad) * sin(declination * rad)) / (cos(latitude * rad) * cos(declination * rad))
    if cosH > 1 then return { sunrise = nil, sunset = nil } end
    if cosH < -1 then return { sunrise = 0, sunset = 24 } end

    local H = acos(cosH) / rad
    local sunrise = 12 - H / 15 + time_offset
    local sunset = 12 + H / 15 + time_offset

    return { sunrise = sunrise, sunset = sunset }
end

-- Главная функция модуля
function p.calculateSunTimes(frame)
    local latitude = 61.783333333333 -- Широта Петрозаводск
    local longitude = 34.366666666667 -- Долгота Петрозаводск
    local timezone = 3 -- Часовой пояс Петрозаводск (UTC+3)

    -- Получаем дату из аргумента или используем текущую
    local dateArg = frame.args["date"] or os.date("!%Y-%m-%d")
    local year, month, day = dateArg:match("(%d+)-(%d+)-(%d+)")
    year, month, day = tonumber(year), tonumber(month), tonumber(day)

    -- Расчет Юлианской даты
    local jd = calculateJulianDate(year, month, day)
    local sunTimes = calculateSunTimesForDate(jd, latitude, longitude)

    -- Перевод времени в локальный часовой пояс
    local sunriseUTC = sunTimes.sunrise
    local sunsetUTC = sunTimes.sunset

    local sunriseLocal = sunriseUTC and (sunriseUTC + timezone) or nil
    local sunsetLocal = sunsetUTC and (sunsetUTC + timezone) or nil

    -- Форматирование результата
    if sunriseLocal and sunsetLocal then
        local sunriseHours = math.floor(sunriseLocal)
        local sunriseMinutes = math.floor((sunriseLocal % 1) * 60)
        local sunsetHours = math.floor(sunsetLocal)
        local sunsetMinutes = math.floor((sunsetLocal % 1) * 60)
        
        local dayLength = sunsetLocal - sunriseLocal
        local dayLengthHours = math.floor(dayLength)
        local dayLengthMinutes = math.floor((dayLength % 1) * 60)
        
        return string.format("[[Petroskoi]]š ☀️[[Päiväine]] nouzeb %d časud %d minutad homendest, laskese %d časud %d minutad ehtad. Päivän piduz' 🕒  %d časud %d minutad. ",
                             sunriseHours, sunriseMinutes, sunsetHours, sunsetMinutes, dayLengthHours, dayLengthMinutes)
    else
        return "Восход и закат не вычислился."
    end
end

return p