Op den Inhalt sprangen

Modul:Alter

Vu Wikipedia
Dokumentatioun vum Modul:Alter [liesen] [änneren] [Versioune weisen]

D'Dokumentatioun fir dëst Modul steet hei ënnendrënner an ass vun der Säit Modul:Alter/doc hei agebonne ginn. Kuckt och: Hëllef:Moduler.

local p = {}
-- Mat der Hëllef vun ChatGPT entwéckelt; manuell iwwerpréift a getest (Juli 2026).

local function hasValue(value)
	return value ~= nil
		and mw.text.trim(tostring(value)) ~= ''
end

-- Wielt eng bevorzugt Ausso; falls keng do ass,
-- gëtt déi éischt normal Ausso benotzt.
local function getBestTimeStatement(property)
	local entity = mw.wikibase.getEntityObject()

	if not entity
		or not entity.claims
		or not entity.claims[property]
	then
		return nil
	end

	local normalStatement = nil

	for _, statement in ipairs(entity.claims[property]) do
		local snak = statement.mainsnak

		if snak
			and snak.snaktype == 'value'
			and snak.datavalue
			and snak.datavalue.type == 'time'
		then
			if statement.rank == 'preferred' then
				return snak.datavalue.value
			end

			if statement.rank == 'normal' and not normalStatement then
				normalStatement = snak.datavalue.value
			end
		end
	end

	return normalStatement
end

local function parseTime(value)
	if not value or not value.time then
		return nil
	end

	local sign, year, month, day =
		value.time:match('^([%+%-])(%d+)%-(%d%d)%-(%d%d)T')

	if not year then
		return nil
	end

	year = tonumber(year)
	month = tonumber(month)
	day = tonumber(day)

	if sign == '-' then
		year = -year
	end

	return {
		year = year,
		month = month,
		day = day,
		precision = tonumber(value.precision)
	}
end

local function isLeapYear(year)
	return year % 400 == 0
		or (year % 4 == 0 and year % 100 ~= 0)
end

local function daysInMonth(year, month)
	local days = {
		31, 28, 31, 30, 31, 30,
		31, 31, 30, 31, 30, 31
	}

	if month == 2 and isLeapYear(year) then
		return 29
	end

	return days[month]
end

-- Bestëmmt de fréisten an de spéitste méiglechen Datum.
local function dateRange(date)
	if not date or not date.year or date.year < 1 then
		return nil
	end

	-- Präzisioun 11 oder méi: geneeën Dag
	if date.precision >= 11
		and date.month >= 1
		and date.day >= 1
	then
		local exactDate = {
			year = date.year,
			month = date.month,
			day = date.day
		}

		return exactDate, exactDate
	end

	-- Präzisioun 10: Joer a Mount
	if date.precision == 10
		and date.month >= 1
	then
		return {
			year = date.year,
			month = date.month,
			day = 1
		}, {
			year = date.year,
			month = date.month,
			day = daysInMonth(date.year, date.month)
		}
	end

	-- Präzisioun 9: nëmmen d'Joer
	if date.precision == 9 then
		return {
			year = date.year,
			month = 1,
			day = 1
		}, {
			year = date.year,
			month = 12,
			day = 31
		}
	end

	-- Joerzéngt, Joerhonnert asw. sinn ze onpräzis.
	return nil
end

local function fullYears(birthDate, endDate)
	local age = endDate.year - birthDate.year

	if endDate.month < birthDate.month
		or (
			endDate.month == birthDate.month
			and endDate.day < birthDate.day
		)
	then
		age = age - 1
	end

	return age
end

local function currentDate(frame)
	-- Dës Parservariabele suergen och dofir,
	-- datt den Datum beim Cache-Aktualiséiere nei berechent gëtt.
	return {
		year = tonumber(frame:preprocess('{{CURRENTYEAR}}')),
		month = tonumber(frame:preprocess('{{CURRENTMONTH}}')),
		day = tonumber(frame:preprocess('{{CURRENTDAY2}}'))
	}
end

local function formatAge(minAge, maxAge)
	if not minAge
		or not maxAge
		or minAge < 0
		or maxAge < 0
	then
		return ''
	end

	if minAge == maxAge then
		return tostring(minAge) .. '&nbsp;Joer'
	end

	return tostring(minAge)
		.. '&nbsp;/&nbsp;'
		.. tostring(maxAge)
		.. '&nbsp;Joer'
end

function p.alter(frame)
	local args = frame.args

	-- Soubal Gebuer oder Gestuerwen an der Infobox
	-- manuell ausgefëllt ass, gëtt näischt automatesch gerechent.
	if hasValue(args.gebuer) or hasValue(args.gestuerwen) then
		return ''
	end

	local birth =
		parseTime(getBestTimeStatement('P569'))

	if not birth then
		return ''
	end

	local birthEarliest, birthLatest = dateRange(birth)

	if not birthEarliest or not birthLatest then
		return ''
	end

	local death =
		parseTime(getBestTimeStatement('P570'))

	local endEarliest
	local endLatest

	if death then
		endEarliest, endLatest = dateRange(death)

		if not endEarliest or not endLatest then
			return ''
		end
	else
		endEarliest = currentDate(frame)
		endLatest = endEarliest
	end

	local minAge =
		fullYears(birthLatest, endEarliest)

	local maxAge =
		fullYears(birthEarliest, endLatest)

	return formatAge(minAge, maxAge)
end

return p