Module:Dates

From OpenStreetMap Wiki
Jump to navigation Jump to search
[Edit] [Purge] Documentation

Utilities for working with dates.

format

This function takes one or two timestamps and formats them in a human-readable way according to the specified language code. See Module talk:Dates/testcases for unit tests that double as usage examples. Module:Dates/locales defines the formats for each language.

See also

local p = {}
local english = mw.getContentLanguage()

local formatsByLanguage = mw.loadData("Module:Dates/locales")

local function pageLanguage(frame)
	local title = mw.title.getCurrentTitle()
	
	-- Language-specific namespace
	local ns = title.subjectNsText
	if #ns == 2 then
		return ns:lower()
	end
	
	-- Pseudo-namespace in the main namespace
	local pseudoNS = title.text:match("^(%w[-%w]+):")
	if pseudoNS then
		return pseudoNS:lower()
	end
	
	-- Current page language
	return mw.getCurrentFrame():preprocess("{{PAGELANGUAGE}}")
end

local function parseDate(timestamp)
	return os.date("*t", tonumber(english:formatDate("U", timestamp)))
end

function p.format(frame)
	local lang = mw.getLanguage(frame.args.lang and #frame.args.lang > 0 and frame.args.lang or pageLanguage(frame))
	local formats = formatsByLanguage[lang:getCode()] or formatsByLanguage.en
	
	local currentDate = os.date("*t")
	local startDate = frame.args[1] and #frame.args[1] > 0 and parseDate(frame.args[1]) or currentDate
	local endDate = frame.args[2] and #frame.args[2] > 0 and parseDate(frame.args[2]) or startDate
	assert(startDate.year < endDate.year or
		(startDate.year == endDate.year and startDate.yday <= endDate.yday),
		"Start date must precede end date")
	
	local startFormat, endFormat
	if startDate.year == endDate.year then
		if startDate.month == endDate.month then
			if startDate.day == endDate.day then
				startFormat = formats.sameDay[1]
			else
				startFormat = formats.sameMonth[1]
				endFormat = formats.sameMonth[2]
			end
		else
			startFormat = formats.sameYear[1]
			endFormat = formats.sameYear[2]
		end
	else
		startFormat = formats.different[1]
		endFormat = formats.different[2]
	end
	
	formattedDate = lang:formatDate(startFormat, frame.args[1])
	if endFormat ~= nil then
		local formattedEnd = lang:formatDate(endFormat, frame.args[2])
		formattedDate = mw.ustring.gsub(formattedDate, "…", formattedEnd)
	end
	
	return formattedDate
end

return p