Module:AjoutDates

De Wikirouge
Aller à la navigation Aller à la recherche

Module Lua invoqué par {{AjoutDates}}


-- Module:AjoutDates
-- Formats saisis : JJ/MM/AAAA, MM/AAAA, AAAA (année éventuellement négative = BC)
-- Sortie SMW : ISO pour dates positives ; "J Month AAAA BC" pour négatives
-- Convention retenue : -0370 = "370 BC" (le nombre saisi EST le millésime av. J.-C.)
local p = {}

local MONTHS_EN = {
	'January', 'February', 'March', 'April', 'May', 'June',
	'July', 'August', 'September', 'October', 'November', 'December'
}

local function isYear( v )
	return v:match( '^%-?%d+$' ) ~= nil and #( v:gsub( '^%-', '' ) ) <= 4
end

local function isNum( v )
	return v:match( '^%d+$' ) ~= nil
end

local function parseDate( raw )
	raw = mw.text.trim( raw or '' )
	if raw == '' then
		return nil
	end

	local parts = mw.text.split( raw, '/' )
	local n = #parts
	local day, month, year

	if n == 1 then
		year = parts[1]
		if not isYear( year ) then return { valid = false } end
	elseif n == 2 then
		month, year = parts[1], parts[2]
		if not isNum( month ) or not isYear( year ) then return { valid = false } end
		if tonumber( month ) < 1 or tonumber( month ) > 12 then return { valid = false } end
	elseif n == 3 then
		day, month, year = parts[1], parts[2], parts[3]
		if not isNum( day ) or not isNum( month ) or not isYear( year ) then return { valid = false } end
		if tonumber( day ) < 1 or tonumber( day ) > 31 then return { valid = false } end
		if tonumber( month ) < 1 or tonumber( month ) > 12 then return { valid = false } end
	else
		return { valid = false }
	end

	local isBC = year:sub( 1, 1 ) == '-'
	local absYear = year:gsub( '^%-', '' )
	local iso

	if isBC then
		-- SMW n'accepte pas l'entrée numérique négative : on sort en "BC"
		-- avec nom de mois anglais (le parseur SMW est anglophone)
		local monthName = month and MONTHS_EN[ tonumber( month ) ] or nil
		if day and monthName then
			iso = string.format( '%s %s %s BC', tostring( tonumber( day ) ), monthName, absYear )
		elseif monthName then
			iso = string.format( '%s %s BC', monthName, absYear )
		else
			iso = string.format( '%s BC', absYear )
		end
	else
		-- Dates positives : ISO partiel propre
		if n == 1 then
			iso = year
		elseif n == 2 then
			iso = string.format( '%s-%02d', year, tonumber( month ) )
		else
			iso = string.format( '%s-%02d-%02d', year, tonumber( month ), tonumber( day ) )
		end
	end

	return {
		valid = true,
		iso = iso,
		day = day or '',
		month = month or '',
	}
end

function p.iso( frame )
	local r = parseDate( frame.args[1] )
	if not r or not r.valid then return '' end
	return r.iso
end

function p.day( frame )
	local r = parseDate( frame.args[1] )
	if not r or not r.valid then return '' end
	return r.day
end

function p.month( frame )
	local r = parseDate( frame.args[1] )
	if not r or not r.valid then return '' end
	return r.month
end

function p.valid( frame )
	local raw = mw.text.trim( frame.args[1] or '' )
	if raw == '' then return '1' end
	local r = parseDate( raw )
	return ( r and r.valid ) and '1' or ''
end

return p