Moduł:WiekLataDni
ocal p = {}
local function trim(v) if v == nil then return nil end v = tostring(v):match("^%s*(.-)%s*$") if v == "" then return nil end return v end
local function isLeap(y) return (y % 4 == 0 and y % 100 ~= 0) or (y % 400 == 0) end
local function daysInMonth(y, m) local t = {31,28,31,30,31,30,31,31,30,31,30,31} if m == 2 and isLeap(y) then return 29 end return t[m] end
local function isValidDate(y, m, d) if not y or not m or not d then return false end if m < 1 or m > 12 then return false end if d < 1 or d > daysInMonth(y, m) then return false end return true end
local function daysBeforeYear(y) y = y - 1 return 365 * y + math.floor(y / 4) - math.floor(y / 100) + math.floor(y / 400) end
local function serialDay(y, m, d) local n = d for i = 1, m - 1 do n = n + daysInMonth(y, i) end return daysBeforeYear(y) + n end
local function pluralYears(n) local mod10 = n % 10 local mod100 = n % 100
if mod10 == 1 and mod100 ~= 11 then return "rok" elseif mod10 >= 2 and mod10 <= 4 and not (mod100 >= 12 and mod100 <= 14) then return "lata" else return "lat" end end
local function pluralDays(n) if n == 1 then return "dzień" end return "dni" end
local function getCurrentDate(frame) local y = tonumber(frame:preprocess("2026")) local m = tonumber(frame:preprocess("07")) local d = tonumber(frame:preprocess("21")) return y, m, d end
local function getArgs(frame) local parent = frame:getParent() local src = frame.args
if parent and next(parent.args) then src = parent.args end
local args = {} for k, v in pairs(src) do args[k] = trim(v) end return args end
function p.policz(frame) local args = getArgs(frame)
local y1 = tonumber(args[1] or args.rok1 or args.rok) local m1 = tonumber(args[2] or args.miesiac1 or args.miesiąc1 or args.miesiac or args.miesiąc) local d1 = tonumber(args[3] or args.dzien1 or args.dzień1 or args.dzien or args.dzień)
local y2 = tonumber(args[4] or args.rok2) local m2 = tonumber(args[5] or args.miesiac2 or args.miesiąc2) local d2 = tonumber(args[6] or args.dzien2 or args.dzień2)
if not isValidDate(y1, m1, d1) then return 'Błąd: nieprawidłowa data początkowa.' end
if y2 or m2 or d2 then if not isValidDate(y2, m2, d2) then return 'Błąd: nieprawidłowa data końcowa.' end else y2, m2, d2 = getCurrentDate(frame) end
local startSerial = serialDay(y1, m1, d1) local endSerial = serialDay(y2, m2, d2)
if endSerial < startSerial then return 'Błąd: data końcowa jest wcześniejsza niż początkowa.' end
local years = y2 - y1 local annivDayInEndYear = math.min(d1, daysInMonth(y2, m1))
if (m2 < m1) or (m2 == m1 and d2 < annivDayInEndYear) then years = years - 1 end
local annivYear = y1 + years local annivDay = math.min(d1, daysInMonth(annivYear, m1)) local anniversarySerial = serialDay(annivYear, m1, annivDay)
local days = endSerial - anniversarySerial
return years .. " " .. pluralYears(years) .. " i " .. days .. " dni" end
return p