Zweck Bearbeiten

Das Modul DateFormat dient der sprachspezifischen Formatierung von Datums- und Zeitangaben in MediaWiki. Es nutzt Lua und erlaubt einfache, konsistente Ausgabeformate – vorrangig im deutschen Stil (TT.MM.JJJJ), unterstützt aber auch andere Sprachen wie Englisch.

Funktionen Bearbeiten

formatDate Bearbeiten

Formatiert ein Datum gemäß Sprachkonvention.

Aufruf
{{#invoke:DateFormat|formatDate|2025-06-13}}
Parameter
  • 1 – Das Eingabedatum (ISO 8601 empfohlen: JJJJ-MM-TT oderJJJJ-MM-TT hh:mm:ss, bzw. JJJJ-MM-TTThh:mm:ss)
    • Achtung: Die Uhrzeit muss entweder durch ein Leerzeichen , oder den im ISO-Format gebräuchlichen Trenner (für Time) T als Trennzeichen eingegeben werden.
    • Damit due Uhrzeit auch ausgegeben wird, bitte den Parameter time zusätzlich auf 1 setzen.
  • lang – (optional) Sprachcode, z. B. de, en
  • time – (optional) Bei 1 wird auch die Uhrzeit ausgegeben.
Beispiele
  • 13.06.202513.06.2025
  • 2025-06-13 15:422025-06-13 15:42

relativeDate Bearbeiten

Berechnet eine relative Angabe („vor 3 Tagen“, „2 hours ago“).

Aufruf
{{#invoke:DateFormat|relativeDate|2025-06-10}}
Parameter
  • 1 – Eingabedatum (ISO-Format empfohlen)
  • lang – (optional) Sprachcode, z. B. de, en
Beispiel
  • vor 6 Monatenvor 3 Tagen

Unterstützte Sprachen Bearbeiten

Aktuell:

  • de – Deutsch (Standard)
  • en – Englisch

Weitere Sprachen können bei Bedarf ergänzt werden.

Hinweise Bearbeiten

  • Ungültige oder nicht parsbare Datumsangaben geben eine Fehlermeldung wie Ungültiges Datum zurück.
  • Relativangaben basieren auf der Serverzeit und rechnen in Sekunden, Minuten, Stunden, Tagen, Monaten oder Jahren.

Wartung Bearbeiten

Dieses Modul ist Teil der zentralen Formatierungswerkzeuge und sollte vor Funktionsänderungen abgesichert und ggf. versioniert werden.

Siehe auch Bearbeiten


local p = {}

local langFormats = {
	["de"] = {
		date = "%d.%m.%Y",
		datetime = "%d.%m.%Y %H:%M",
		ago = {
			second = "vor %d Sekunden",
			minute = "vor %d Minuten",
			hour =   "vor %d Stunden",
			day =    "vor %d Tagen",
			month =  "vor %d Monaten",
			year =   "vor %d Jahren"
		}
	},
	["en"] = {
		date = "%Y-%m-%d",
		datetime = "%Y-%m-%d %H:%M",
		ago = {
			second = "%d seconds ago",
			minute = "%d minutes ago",
			hour =   "%d hours ago",
			day =    "%d days ago",
			month =  "%d months ago",
			year =   "%d years ago"
		}
	}
	-- weitere Sprachen ergänzbar
}

local function getFormat(lang, withTime)
	local formats = langFormats[lang] or langFormats["de"]
	return withTime and formats.datetime or formats.date
end

function p.formatDate(frame)
	local args = frame.args
	local date = args[1]
	local lang = args.lang or "de"
	local withTime = args.time == "1"

	local t = mw.getContentLanguage():formatDate("c", date)
	if not t then return "Ungültiges Datum" end

	local ts = mw.text.split(t, "[T ]")
	local datePart, timePart = ts[1], ts[2] or "00:00"

	local year, month, day = datePart:match("(%d+)%-(%d+)%-(%d+)")
	local hour, minute = timePart:match("(%d+):(%d+)")

	local dateObj = {
		year = tonumber(year),
		month = tonumber(month),
		day = tonumber(day),
		hour = tonumber(hour),
		min = tonumber(minute)
	}

	local timeString = os.time(dateObj)
	return os.date(getFormat(lang, withTime), timeString)
end

function p.relativeDate(frame)
	local args = frame.args
	local timestamp = args[1]
	local lang = args.lang or "de"
	local t = mw.getContentLanguage():formatDate("c", timestamp)
	if not t then return "?" end

	local datePart = mw.text.split(t, "[T ]")[1]
	local year, month, day = datePart:match("(%d+)%-(%d+)%-(%d+)")
	if not (year and month and day) then return "?" end

	local then_ = os.time({
		year = tonumber(year),
		month = tonumber(month),
		day = tonumber(day),
		hour = 12  -- neutraler Mittelwert gegen Zeitzonenprobleme
	})

	local now = os.time()
	local diff = now - then_
	local ago = langFormats[lang] and langFormats[lang].ago or langFormats["de"].ago

	local units = {
		{ name = "year", secs = 31536000 },
		{ name = "month", secs = 2592000 },
		{ name = "day", secs = 86400 },
		{ name = "hour", secs = 3600 },
		{ name = "minute", secs = 60 },
		{ name = "second", secs = 1 }
	}

	for _, u in ipairs(units) do
		local value = math.floor(diff / u.secs)
		if value > 0 then
			return string.format(ago[u.name], value)
		end
	end
	return (lang == "en" and "just now") or "gerade eben"
end

return p