Zum Inhalt springen

Modul:DateFormat

Aus Wikonia

Zweck[Quelltext 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[Quelltext bearbeiten]

formatDate[Quelltext 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[Quelltext 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[Quelltext bearbeiten]

Aktuell:

  • de – Deutsch (Standard)
  • en – Englisch

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

Hinweise[Quelltext 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[Quelltext bearbeiten]

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

Siehe auch[Quelltext 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