Aller au contenu

Module:Durée

Cette page fait l’objet d’une mesure de semi-protection étendue.
Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 18 décembre 2021 à 10:09 et modifiée en dernier par Epok (discuter | contributions) (Ajustement du comportement par défaut de "en jours", "en mois" et "en années" pour refléter le comportement de base du module en termes de texte affiché.). Elle peut contenir des erreurs, des inexactitudes ou des contenus vandalisés non présents dans la version actuelle.

 Documentation[voir] [modifier] [historique] [purger]

Utilisation

Fonctions exportables :

  • duree(frame) – Fonction principale utilisable dans les modèles.
  • _duree(args) – Fonction pour utilisation dans d'autres modules avec le tableau des paramètres.

Autres fonctions :

  • joursMois(m, a)
  • erreur(texte)
  • determinationMois(mois)


local p = {}

local Outils = require 'Module:Outils'

-- liste des mois, écriture exacte et simplifiée, en minuscule
local liste_mois = {
	{ "janvier", "jan.", "janv.", "jan", "janv", "january", nJour = 31 },
	{ "février", "fevrier", "fev.", "fev", "fév.", "fév", "february", nJour = 28 },
	{ "mars", "mar.", "mar", "march", nJour = 31 },
	{ "avril", "avr.", "avr", "apr", "april", nJour = 30 },
	{ "mai", "may", nJour = 31 },
	{ "juin", "jun", "june", nJour = 30 },
	{ "juillet", "juil.", "juil", "juill.", "juill", "jul", "july", nJour = 31 },
	{ "août", "aout", "aou", "aug", "august", nJour = 31 },
	{ "septembre", "sept.", "sept", "sep.", "sep", "september", nJour = 30 },
	{ "octobre", "oct.", "oct", "october", nJour = 31 },
	{ "novembre", "nov.", "nov", "november", nJour = 30 },
	{ "décembre", "decembre", "déc.", "dec.", "dec", "déc", "december", nJour = 31 },
}

local function joursMois( m, a )
	a = a or 1
	if m == 0 then
		return 31
	elseif m == 2 then
		local b = ( a % 4 == 0 ) and ( ( a % 100 ~= 0 ) or ( a % 400 == 0 ) )
		return 28 + ( b and 1 or 0 )
	else
		return liste_mois[m].nJour
	end
end

function erreur( texte )
	local cat = '[[Catégorie:Page utilisant un modèle avec une syntaxe erronée|Durée]]'
	local message = '<span class="error">erreur : '  .. texte .. '</span>'
	local ns = mw.title.getCurrentTitle().namespace
	if ns == 0 then
		return message .. cat
	else
		return message
	end
end

---
local function determinationMois( mois )
	if tonumber( mois ) then
		local num = math.floor( tonumber( mois ) )
		if num > 0 and num <= 12 then
			return num
		end
	elseif type( mois ) == 'string' and mw.text.trim( mois ) ~= '' then
		local nom = mw.ustring.lower( mois )
		for num = 1, 12 do
			local i = 1
			while liste_mois[num][i] do
				if liste_mois[num][i] == nom then
					return num
				end
				i = i + 1
			end
		end
	end
end

function p._duree( args )
	local maintenant = os.date( '!*t' )
	local fuseau = mw.getContentLanguage():formatDate("Z", nil, true)/3600
	if maintenant.hour + fuseau > 23 then
		maintenant.day = maintenant.day + 1
	end

	local enjours = args["en jours"]
	local enmois = args["en mois"]
	local enanneesetjours = args["en années et jours"]
	local enannee = not enanneesetjours and (args["en année"] or args["en années"])
	local raw = (args["raw"] and args["raw"] ~= "-") or (args["brut"] and args["brut"] ~= "-")

	local precision = 'jour'
	local jour1 = tonumber( args[1] )
	local mois1 = determinationMois( args[2] )
	local annee1 = tonumber( args[3] )
	if jour1 and jour1 > 31 and (not annee1 or annee1 <= 31) then
		local y = jour1
		jour1 = annee1
		annee1 = y
	end
	if not jour1 then
		precision = 'mois'
		-- jour1 = maintenant.day
		jour1 = 1
	end
	if not mois1 then 
		if precision == 'mois' then
			precision = 'an'
			-- mois1 = maintenant.month
			mois1 = 1
		else
			return erreur( 'mois invalide (' .. ( args[2] or '' ) .. ')' )
		end
	end
	if not annee1 then
		if precision == 'an' then
			return
			-- return erreur( 'aucune année fournit' ) -- suggestion
		else
			annee1 = maintenant.year
		end
	end

	local jour2 = tonumber( args[4] ) or maintenant.day
	local mois2 = determinationMois( args[5] ) or maintenant.month
	local annee2 = tonumber( args[6])  or maintenant.year
	if jour2 > 31 and annee2 <= 31 then
		local y = jour2
		jour2 = annee2
		annee2 = y
	end
		
	local tri = os.difftime(
		os.time{ year = annee2, month = mois2, day = jour2 },
		os.time{ year = annee1, month = mois1, day = jour1 }
		) / 86400
	if tri < 0 then
		return erreur( 'durée inférieure à 0' )
	end
	local nbjours = tri
	tri = 0 .. tostring( tri )
	tri = string.rep( '&', 16 - #tri ) .. tri
	
	if enjours then
		if raw then
			return nbjours
		else
			local moduleUnite = require 'Module:Unité'
			local unit
			if not args['masquer texte'] or args['masquer texte'] == '' then 
				if nbjours> 1 then unit = 'jours' else unit = 'jour' end
			end
			nbjours = moduleUnite._unite({nbjours, unit})
			return mw.text.tag{ 
				name = 'span', 
				attrs = { class = 'datasortkey', ['data-sort-value'] = tri }, 
				content = nbjours
			}
		end
	end

	local njour = jour2 - jour1
	local nmois = mois2 - mois1
	local nannee = annee2 - annee1
	if njour < 0 then
		nmois = nmois - 1
		njour = njour + joursMois( mois2 - 1, annee2 )
	end
	if nmois < 0 then
		nannee = nannee - 1
		nmois = nmois + 12
	end

	if enmois then
		local nbmois = nannee * 12 + nmois
		if raw then
			return nbmois
		else
			local moduleUnite = require 'Module:Unité'
			local unit
			if not args['masquer texte'] or args['masquer texte'] == '' then
				unit = 'mois'
			end
			nbmois = moduleUnite._unite({nbmois, unit})
			return mw.text.tag{ 
				name = 'span', 
				attrs = { class = 'datasortkey', ['data-sort-value'] = tri }, 
				content = nbmois
			}
		end
	end
	if enannee then
		if raw then
			return nannee
		else
			local moduleUnite = require 'Module:Unité'
			local unit
			if not args['masquer texte'] or args['masquer texte'] == '' then 
				if nannee > 1 then unit = 'ans' else unit = 'an' end
			end
			nannee = moduleUnite._unite({nannee, unit})
			return mw.text.tag{ 
				name = 'span', 
				attrs = { class = 'datasortkey', ['data-sort-value'] = tri }, 
				content = nannee
			}
		end
	end

	local result = {}
	local conjunction
	local function add( nombre, singulier, pluriel )
		if nombre > 0 then
			local texte = pluriel
			if nombre == 1 then
				texte = singulier
			end
			table.insert( result, nombre .. '\194\160' .. texte )
		end
	end
	if enanneesetjours then
		conjunction = ', '
		if precision ~= 'an' then
			nannee = annee2 - annee1
			njour = os.difftime(
				os.time{ year = annee2, month = mois2, day = jour2 },
				os.time{ year = annee2, month = mois1, day = jour1 }
				) / 86400
			if njour < 0 then
				nannee = nannee - 1
				njour = os.difftime(
					os.time{ year = annee2, month = mois2, day = jour2 },
					os.time{ year = annee2, month = 1, day = 1}
					) / 86400
					+ os.difftime(
					os.time{ year = annee1 + 1, month = 1, day = 1},
					os.time{ year = annee1, month = mois1, day = jour1 }
					) / 86400
			end
			add( nannee, 'an', 'ans' )
			add( njour, 'jour', 'jours' )
		else
			add( nannee, 'an', 'ans' )
		end
	else
		add( nannee, 'an', 'ans' )
		if precision ~= 'an' then
			add( nmois, 'mois', 'mois' )
		end
		if precision == 'jour' then
			add( njour, 'jour', 'jours' )
		end
	end

	if #result == 0 then
		result[1] = 'moins d’un ' .. precision
		tri = 0
	end

	return mw.text.tag{ 
		name = 'span', 
		attrs = { class = 'datasortkey', ['data-sort-value'] = tri }, 
		content = mw.text.listToText( result, nil, conjunction )
	}
end


function p.duree( frame )
	local args = Outils.extractArgs( frame )
	for i = 1, 6 do
		if tonumber( args[i] ) == 0 then
			args[i] = ''
		end
	end
	args[1] = args[1] or args['année']
	args[2] = args[2] or args['mois']
	args[3] = args[3] or args['jour']

	return p._duree( args )
end

return p