« Module:Date » : différence entre les versions
Demande de Zebulon84 : rendre le tiret insécable dans "av J.-C." |
copie de Module:Date/Bac à sable : permet {{date|22 avril 1015}} et Modèle:Date-, et amélioration diverses. (voir WP:DIPP#Module:Date (d · h · j · ↵) |
||
Ligne 3 : | Ligne 3 : | ||
local TableBuilder = require( 'Module:TableBuilder' ) |
local TableBuilder = require( 'Module:TableBuilder' ) |
||
local Outils = require( 'Module:Outils' ) |
local Outils = require( 'Module:Outils' ) |
||
-- chargement de la base de donnée répertoriant certaines pages existant ou n'existant pas pour éviter les "ifexist". |
|||
local dataLiens |
|||
local success, resultat = pcall ( mw.loadData, 'Module:Date/Data' ) |
|||
if success then |
|||
dataLiens = resultat |
|||
else |
|||
-- protection au cas ou le sous module serait mal modifié |
|||
dataLiens = { [''] = { mois = { aucun = 1000, tous = { 1773, 2014 } }, } } |
|||
end |
|||
-- nettoie un paramètre non nommé (vire les espaces au début et à la fin) |
-- nettoie un paramètre non nommé (vire les espaces au début et à la fin) |
||
Ligne 28 : | Ligne 36 : | ||
{ "novembre", "nov.", "nov", "november", nJour = 30 }, |
{ "novembre", "nov.", "nov", "november", nJour = 30 }, |
||
{ "décembre", "decembre", "déc.", "dec.", "dec", "déc", "december", nJour = 31 }, |
{ "décembre", "decembre", "déc.", "dec.", "dec", "déc", "december", nJour = 31 }, |
||
} |
|||
local liste_saison = { |
|||
{ 'printemps', 'spring', }, |
|||
{ 'été', 'summer', }, |
|||
{ 'automne', 'autumn', }, |
|||
{ 'hiver', 'winter', }, |
|||
} |
} |
||
Ligne 54 : | Ligne 69 : | ||
if liste_mois[i][j] == m then |
if liste_mois[i][j] == m then |
||
return liste_mois[i][1], i |
return liste_mois[i][1], i |
||
end |
|||
j = j + 1 |
|||
end |
|||
end |
|||
-- pas trouvé = return nil |
|||
end |
|||
--- |
|||
-- valide que la chaîne passée est un mois valide. |
|||
-- retourne le nom complet ou nil si non reconnu |
|||
-- si reconnu, retourne aussi le numéro du mois [1-12] |
|||
function fun.valideSaison( saison ) |
|||
if type( saison ) ~= "string" then |
|||
return nil |
|||
end |
|||
local m = mw.ustring.lower( mw.text.trim( saison ) ) |
|||
for i = 1, 4 do |
|||
local j = 1 |
|||
while liste_saison[i][j] ~= nil do |
|||
if liste_saison[i][j] == m then |
|||
return liste_saison[i][1] |
|||
end |
end |
||
j = j + 1 |
j = j + 1 |
||
Ligne 64 : | Ligne 102 : | ||
-- determinationMois trouve le numéro du mois et son nom, |
-- determinationMois trouve le numéro du mois et son nom, |
||
-- à partir de son nom, de son numéro ou d'une expression mathématique. |
-- à partir de son nom, de son numéro ou d'une expression mathématique. |
||
-- Si le deuxième paramètre est vrai, les nombres supérieur à 12 ou non entiers sont acceptés. |
|||
-- l'objet frame est facultatif, mais permet de tester si mois est une expression type '2+3' |
|||
function fun.determinationMois( mois, |
function fun.determinationMois( mois, mod, boucle ) |
||
local num, nom |
local num, nom |
||
if tonumber( mois ) then |
if tonumber( mois ) then |
||
num = math.floor |
num = math.floor( tonumber( mois ) ) |
||
if mod then |
|||
elseif type( mois ) == "string" then |
|||
-- si le nombre du mois est calculé par une exression, le résultat peut être supérieur à 12, ou inférieur à 1 |
|||
num = math.fmod( num + 239, 12 ) + 1 -- +239 car fmod(-1) = -1 et non 11 |
|||
elseif num < 1 or num > 12 then |
|||
num = nil |
|||
end |
|||
elseif trim( mois ) then |
|||
nom, num = fun.valideMois( mois ) |
nom, num = fun.valideMois( mois ) |
||
if nom == nil and |
if nom == nil and boucle == nil then |
||
-- essai de détermination d'un nombre avec le parser #expr de Mediawiki. |
-- essai de détermination d'un nombre avec le parser #expr de Mediawiki. |
||
-- |
-- le paramètre boucle évite de tourner en boucle. |
||
nom, num = fun.determinationMois( |
nom, num = fun.determinationMois( mw.getCurrentFrame():callParserFunction( '#expr', mois ), true, true ) |
||
end |
end |
||
end |
end |
||
Ligne 130 : | Ligne 174 : | ||
--- |
--- |
||
-- Supprime le jour de la semaine, et "le" avant une date |
|||
-- émule le modèle {{m|Date}}. |
|||
function fun.nettoyageJour( jour ) |
|||
-- Paramètres : |
|||
if type( jour ) == 'string' then |
|||
-- 1 : jour (numéro ou "1er"). optionnel, si absent pas de jour |
|||
local nomJour = { '[Ll]undi', '[Mm]ardi', '[Mm]ercredi', '[Jj]eudi', '[Vv]endredi', |
|||
-- 2 : mois (en toutes lettres) |
|||
'[Ss]amedi', '[Dd]imanche', '^ *[Ll]e' } |
|||
-- 3 : année (nombre) |
|||
local premier = { '<abbr class="abbr" title="Premier" >1<sup>er</sup></abbr>', '1er' } |
|||
-- 4 : optionnel, spécialité de l'année |
|||
for i, v in ipairs( nomJour ) do |
|||
-- Comportement spécial ("truc à deux balles au lieu d'utiliser un |
|||
jour = jour:gsub( v, '' ) |
|||
-- paramètre nommé du genre "sans année=oui"...") : si 1 est vide |
|||
end |
|||
-- mais que le reste est complet → on n'affiche pas l'année |
|||
for i, v in ipairs( premier ) do |
|||
function fun.modeleDate( frame ) |
|||
jour = jour:gsub( v, '1' ) |
|||
local args = Outils.extractArgs( frame ) |
|||
end |
|||
jour = mw.text.trim( jour ) |
|||
end |
|||
return jour |
|||
end |
|||
--- |
|||
-- sépare une chaine date en un tabel contenant les champs jour, mois annee. |
|||
function fun.separationJourMoisAnnee( date, decalage, args ) |
|||
date = trim( date ) |
|||
if date then |
|||
local function erreur( periode, valeur ) |
|||
return false, Outils.erreur( periode .. ' invalide (' .. valeur .. ')' ) |
|||
end |
|||
decalage = decalage or 0 |
|||
args = args or {} |
|||
date = fun.nettoyageJour( date ) |
|||
local annee = string.match( date, '^%d%d%d%d?$' ) |
|||
if annee then |
|||
return fun.validationJourMoisAnnee{ '', '', annee, args[2 + decalage], decalage = decalage } |
|||
end |
|||
-- test date au format jj-mm-aaaa |
|||
local j, m, a = string.match( date, '^([0-3]?%d)-([^ /-]+)-*(%d*[ AVJCavjc.-]*)$' ) |
|||
if not m then |
|||
-- test date aux formats jj/mm/aaaa ou dd mmm aaaa |
|||
j, m, a = string.match( date, '^([0-3]?%d)[ /]+([^ /-]+)[ /]*(-?%d*[ AVJCavjc.-]*)$' ) |
|||
end |
|||
if not m then |
|||
-- test date aux formats aaaa-mm-jj, aaaa/mm/jj et aaaa mmm jj |
|||
a, m, j = string.match( date, '^(-?%d%d*)[ /-]+([^ /-]+)[ /-]*([0-3]?%d?)$' ) |
|||
end |
|||
if not m then |
|||
-- test date aux formats mm/aaaa ou mmm aaaa |
|||
m, a = string.match( date, '^([^ /-]+)-?[ /]*(-?%d*[ AVJCavjc.]*)$' ) |
|||
end |
|||
if m then |
|||
if decalage < 0 then |
|||
decalage = decalage + 2 |
|||
end |
|||
if tonumber( j ) and tonumber( j ) > 31 and tonumber( a ) and tonumber( a ) < 31 then |
|||
-- la date est au format aaaa/mm/jj |
|||
return fun.validationJourMoisAnnee{ a, m, j, args[2 + decalage], decalage = decalage } |
|||
else |
|||
return fun.validationJourMoisAnnee{ j, m, a, args[2 + decalage], decalage = decalage } |
|||
end |
|||
else |
|||
return erreur( 'Date', date ) |
|||
end |
|||
else |
|||
return true, {} |
|||
end |
|||
end |
|||
-- chargement de la base de donnée répertoriant certaines pages existant ou n'existant pas pour éviter les "ifexist". |
|||
--- |
|||
local dataLiens |
|||
-- separationJourMoisAnnee prend jusqu'a cinq paramètre et essaie de les séparer en jour, mois, annee et qualificatif |
|||
local success, resultat = pcall ( mw.loadData, 'Module:Date/Data' ) |
|||
-- la date peut être dans le premier paramètre ou séparée dans les paramètre 1 à 3 ou 2 à 4. |
|||
if success then |
|||
-- Le qualificatif est cherché dans le paramètre suivant. |
|||
dataLiens = resultat |
|||
-- La fonction retourne true suivit d'une table avec la date en paramètres nommé (sans accent sur année) |
|||
else |
|||
-- ou false suivit d'un message d'erreur. |
|||
-- protection au cas ou le sous module serait mal modifié |
|||
function fun.validationJourMoisAnnee( frame, ... ) |
|||
dataLiens = { [''] = { mois = { aucun = 1000, tous = { 1938, 2013 } }, } } |
|||
local args = Outils.extractArgs( frame, ... ) |
|||
local jour, mois, numMois, annee, qualificatif, erreur |
|||
args[1] = tostring( args[1] or args['jour'] or '' ) |
|||
args[2] = tostring( args[2] or args['mois'] or '' ) |
|||
args[3] = tostring( args[3] or args['annee'] or args['année'] or '') |
|||
args[4] = tostring( args[4] or '' ) |
|||
local function erreur( periode, valeur ) |
|||
return false, Outils.erreur( periode .. ' invalide (' .. valeur .. ')' ) |
|||
end |
end |
||
local annee, mois, numMois, jour |
|||
local decalage = 0 |
local decalage = 0 |
||
-- si pas de jour mais que args[2] est un mois on décale tout et on |
-- si pas de jour mais que args[2] est un mois on décale tout et on |
||
-- n'affiche pas l'année |
-- n'affiche pas l'année |
||
local arg1, arg2, arg3 = trim( args[1] ), trim( args[2] ), trim( args[3] ) |
|||
if arg1 == nil and arg2 and (fun.determinationMois( args[3] ) or arg2:match( '[^ /][ /-].*%d%d$' ) ) then |
|||
decalage = 1 |
decalage = 1 |
||
elseif arg1 == nil and arg2 == nil and arg3 and |
|||
( fun.determinationMois( args[4] ) or arg3:match( '[^ /][ /-].*%d%d$' ) ) then |
|||
decalage = 2 |
|||
elseif arg1 and arg1:match( '%d%d%d$' ) then |
|||
-- l'année est dans le premier paramètre |
|||
decalage = -2 |
|||
elseif not tonumber( args[3] ) and |
|||
tonumber( args[2] ) and tonumber( args[2] ) > 12 and |
|||
fun.determinationMois( args[1] ) |
|||
then |
|||
-- le mois est dans le premier paramètre et l'année dans le deuxième |
|||
decalage = -1 |
|||
end |
end |
||
Ligne 166 : | Ligne 283 : | ||
if annee == nil and type( bannee ) == 'string' then |
if annee == nil and type( bannee ) == 'string' then |
||
-- test si l'année contient av. J.-C. |
-- test si l'année contient av. J.-C. |
||
annee = |
annee = string.match( string.upper( bannee ), '^(%d+)%sAV%.?%s?J%.?%-?C' ) |
||
annee = tonumber( annee ) |
annee = tonumber( annee ) |
||
if annee then |
if annee then |
||
annee = 0 - annee |
annee = 0 - annee |
||
elseif decalage == -2 then |
|||
return fun.separationJourMoisAnnee( bannee, decalage, args ) |
|||
else |
else |
||
return erreur( 'Année', bannee ) |
|||
local namespaceCategorisation = { [0] = true, [4] = true, [10] = true, [14] = true, [100] = true } |
|||
if namespaceCategorisation[ mw.title.getCurrentTitle().namespace ] then |
|||
return Outils.erreur( 'Année invalide (' .. bannee .. ')[[Catégorie:Page utilisant le modèle date avec une syntaxe erronée|A]]') |
|||
else |
|||
return Outils.erreur( 'Année invalide (' .. bannee .. ')') |
|||
end |
|||
end |
end |
||
end |
end |
||
Ligne 186 : | Ligne 300 : | ||
local bmois = args[2 + decalage] |
local bmois = args[2 + decalage] |
||
if Outils.notEmpty( bmois ) then |
if Outils.notEmpty( bmois ) then |
||
mois, numMois = fun. |
mois, numMois = fun.determinationMois( bmois ) |
||
if mois == nil then |
if mois == nil then |
||
mois = fun.valideSaison( bmois ) |
|||
-- on teste si le mois est fourni sous forme numérique |
|||
if mois == nil then |
|||
numMois = tonumber( bmois ) |
|||
if annee then |
|||
mois = fun.nomDuMois( numMois ) |
|||
return erreur( 'Mois', bmois ) |
|||
end |
|||
elseif type( dataLiens[ trim( bmois ) ] ) == 'table' then |
|||
if mois == nil then |
|||
-- le deuxième paramètre est un qualificatif, donc la date est dans le premier paramètre |
|||
local namespaceCategorisation = { [0] = true, [4] = true, [10] = true, [14] = true, [100] = true } |
|||
local bjour = args[1 + decalage] |
|||
if namespaceCategorisation[ mw.title.getCurrentTitle().namespace ] then |
|||
return fun.separationJourMoisAnnee( bjour, decalage, args ) |
|||
return Outils.erreur( 'Mois invalide (' .. bmois .. ')[[Catégorie:Page utilisant le modèle date avec une syntaxe erronée|M]]') |
|||
else |
else |
||
return |
return erreur( 'Mois ou qualificatif', bmois ) |
||
end |
|||
end |
end |
||
else |
else |
||
Ligne 205 : | Ligne 320 : | ||
if Outils.notEmpty( bjour ) then |
if Outils.notEmpty( bjour ) then |
||
jour = tonumber( bjour ) |
jour = tonumber( bjour ) |
||
if jour == nil |
if jour == nil then |
||
jour = tonumber( fun.nettoyageJour( bjour ) ) |
|||
end |
|||
if bjour == '1er' |
|||
if jour == nil then |
|||
or bjour == '<abbr class="abbr" title="Premier" >1<sup>er</sup></abbr>' -- correspond à {{1er}} |
|||
return erreur( 'Jour', bjour ) |
|||
then |
|||
jour = 1 |
|||
else |
|||
local namespaceCategorisation = { [0] = true, [4] = true, [10] = true, [14] = true, [100] = true } |
|||
if namespaceCategorisation[ mw.title.getCurrentTitle().namespace ] then |
|||
return Outils.erreur( 'Jour invalide (' .. bjour .. ')[[Catégorie:Page utilisant le modèle date avec une syntaxe erronée|J]]') |
|||
else |
|||
return Outils.erreur( 'Jour invalide (' .. bjour .. ')') |
|||
end |
|||
end |
|||
end |
end |
||
-- on valide que le jour est correct |
-- on valide que le jour est correct |
||
if jour < 1 or jour > 31 then |
if jour < 1 or jour > 31 then |
||
return |
return erreur( 'Jour', bjour ) |
||
elseif jour > liste_mois[numMois].nJour then |
elseif jour > liste_mois[numMois].nJour then |
||
return erreur( 'Jour', bjour .. bmois ) |
|||
local namespaceCategorisation = { [0] = true, [4] = true, [10] = true, [14] = true, [100] = true } |
|||
if namespaceCategorisation[ mw.title.getCurrentTitle().namespace ] then |
|||
return Outils.erreur( 'Jour invalide (' .. bjour .. ')[[Catégorie:Page utilisant le modèle date avec une syntaxe erronée|J]]') |
|||
else |
|||
return Outils.erreur( 'Jour invalide (' .. bjour .. ')') |
|||
end |
|||
-- l'année bisextile n'est pas testée pour accepter les dates juliennes. |
-- l'année bisextile n'est pas testée pour accepter les dates juliennes. |
||
end |
end |
||
Ligne 241 : | Ligne 342 : | ||
end |
end |
||
end |
end |
||
elseif decalage > -1 then |
|||
-- else |
|||
-- on teste le jour si présent |
|||
-- return Outils.erreur("Le mois est obligatoire") |
|||
local bjour = args[1 + decalage] |
|||
if Outils.notEmpty( bjour ) then |
|||
if annee then |
|||
return erreur( 'Mois', 'absent' ) |
|||
else |
|||
bjour = fun.nettoyageJour( bjour ) |
|||
jour = tonumber( bjour ) |
|||
if jour then |
|||
if jour > 31 or jour < 1 then |
|||
annee = jour |
|||
jour = nil |
|||
else |
|||
return erreur( 'date', 'jour seul : ' .. bjour ) |
|||
end |
|||
else |
|||
return fun.separationJourMoisAnnee( bjour, decalage, args ) |
|||
end |
|||
end |
|||
end |
|||
end |
end |
||
-- on traite le champs optionnel |
-- on traite le champs optionnel |
||
qualificatif = trim( args[4 + decalage] ) or args.qualificatif |
|||
local result = { |
|||
jour = jour, |
|||
mois = mois, |
|||
numMois = numMois, |
|||
annee = annee, |
|||
qualificatif = qualificatif, |
|||
decalage = decalage + ( args.decalage or 0 ) |
|||
} |
|||
return true, result |
|||
end |
|||
--- |
|||
-- émule le modèle {{m|Date}}. |
|||
-- Paramètres : |
|||
-- 1 : jour (numéro ou "1er"). optionnel, si absent pas de jour |
|||
-- 2 : mois (en toutes lettres) |
|||
-- 3 : année (nombre) |
|||
-- 4 : optionnel, spécialité de l'année |
|||
-- Comportement spécial ("truc à deux balles au lieu d'utiliser un |
|||
-- paramètre nommé du genre "sans année=oui"...") : si 1 est vide |
|||
-- mais que le reste est complet → on n'affiche pas l'année |
|||
function fun.modeleDate( frame ) |
|||
local args = Outils.extractArgs( frame ) |
|||
-- séparation des paramètres jour, mois et année si nécessaire |
|||
local test, resultat = fun.validationJourMoisAnnee( args ) |
|||
if not test then |
|||
local namespaceCategorisation = { [0] = true, [4] = true, [10] = true, [14] = true, [100] = true } |
|||
if namespaceCategorisation[ mw.title.getCurrentTitle().namespace ] and |
|||
not Outils.notEmpty( args.nocat ) then |
|||
return resultat .. '[[Catégorie:Page utilisant le modèle date avec une syntaxe erronée]]' |
|||
else |
|||
return resultat |
|||
end |
|||
end |
|||
local annee, mois, numMois, jour = resultat.annee, resultat.mois, resultat.numMois, resultat.jour |
|||
local decalage, qualificatif = resultat.decalage, resultat.qualificatif |
|||
if ( annee or mois or jour ) == nil then |
|||
return |
|||
end |
|||
-- on traite l'age, naissance et mort |
-- on traite l'age, naissance et mort |
||
Ligne 256 : | Ligne 419 : | ||
-- on traite le calendrier |
-- on traite le calendrier |
||
local gannee, gmois, gjour = annee, numMois, jour -- date suivant le calendrier grégorien pour <time> |
local gannee, gmois, gjour = annee, numMois, jour -- date suivant le calendrier grégorien pour <time> |
||
local jannee, jmois, jjour |
local jannee, jmois, jjour = annee, mois, jour -- servira éventuellement à a affiché la date selon le calendrier julien |
||
local julien2, julien3 = nil, nil -- servira éventuellement à a affiché des parenthèses |
local julien2, julien3 = nil, nil -- servira éventuellement à a affiché des parenthèses |
||
local julien = trim( string.lower( args.julien or '' ) ) |
local julien = trim( string.lower( args.julien or '' ) ) |
||
Ligne 262 : | Ligne 425 : | ||
local amj = annee * 10000 + numMois * 100 + jour |
local amj = annee * 10000 + numMois * 100 + jour |
||
if amj < 15821014 then |
if amj < 15821014 then |
||
gannee, gmois, gjour = fun.julianToGregorian( annee, numMois, jour ) |
if annee > 0 then |
||
gannee, gmois, gjour = fun.julianToGregorian( annee, numMois, jour ) |
|||
else |
|||
-- calendrier grégorien proleptique avec année 0. |
|||
gannee, gmois, gjour = fun.julianToGregorian( annee + 1, numMois, jour ) |
|||
end |
|||
elseif julien == 'oui' then |
elseif julien == 'oui' then |
||
gannee, gmois, gjour = fun.julianToGregorian( annee, numMois, jour ) |
gannee, gmois, gjour = fun.julianToGregorian( annee, numMois, jour ) |
||
annee, mois, jour = gannee, liste_mois[gmois][1], gjour |
annee, mois, jour = gannee, liste_mois[gmois][1], gjour |
||
end |
|||
else |
|||
if annee and annee < 0 then |
|||
gannee = gannee + 1 |
|||
end |
end |
||
end |
end |
||
Ligne 276 : | Ligne 448 : | ||
local iso = TableBuilder.new() -- reçois le format date ISO de ce paramètre |
local iso = TableBuilder.new() -- reçois le format date ISO de ce paramètre |
||
local dataQualificatif |
local dataQualificatif, dataCat |
||
if |
if not args.nolinks then |
||
dataQualificatif = dataLiens[qualificatif or ''] |
|||
-- si le qualifiquatif n'est pas dans la base de donnée, on crée une table minimum, |
|||
if type( dataQualificatif ) ~= 'table' then |
|||
-- qui imposera un test sur l'annee, mais considère qu'il n'y a pas de lien sur le jour ou le mois |
|||
-- si le qualifiquatif n'est pas dans la base de donnée, on crée une table minimum, |
|||
dataQualificatif = { qualificatif = ' ' .. qualificatif, annee = { } } |
|||
-- qui imposera un test sur l'annee, mais considère qu'il n'y a pas de lien sur le jour ou le mois |
|||
dataQualificatif = { qualificatif = ' ' .. qualificatif, annee = { } } |
|||
end |
|||
dataCat = dataLiens[dataQualificatif.cat] |
|||
if type( dataCat ) ~= 'table' or dataCat == dataQualificatif then |
|||
dataCat = { qualificatif = '' } |
|||
end |
|||
end |
end |
||
local function wikiLien( lien, texte ) |
|||
local dataCat = dataLiens[dataQualificatif.cat] |
|||
if lien == texte then |
|||
if type( dataCat ) ~= 'table' or dataCat == dataQualificatif then |
|||
return '[[' .. texte .. ']]' |
|||
else |
|||
return '[[' .. lien .. '|' .. texte .. ']]' |
|||
end |
|||
end |
end |
||
Ligne 299 : | Ligne 481 : | ||
end |
end |
||
-- le jour si présent |
-- le jour si présent |
||
local qualifJour = '' |
local qualifJour = '' |
||
if jour then |
if jour then |
||
local texteJour = jour |
|||
-- éphémérides du qualificatif, ou de sa catégorie, ou générale. |
|||
if args.nolinks then |
|||
qualifJour = dataQualificatif.jour and dataQualificatif.qualificatif |
|||
if jour == 1 then |
|||
jour = '<abbr class="abbr" title="premier">1<sup>er</sup></abbr>' |
|||
or '' |
|||
end |
|||
local lien = jour .. ' ' .. mois .. ' ' .. qualifJour |
|||
wikiListe.insert( jour ) |
|||
else |
|||
jour = '<abbr class="abbr" title="premier">1<sup>er</sup></abbr>' |
|||
qualifJour = dataQualificatif.jour and dataQualificatif.qualificatif |
|||
lien = '1er ' .. mois .. ' ' .. qualifJour |
|||
or dataCat.jour and dataCat.qualificatif |
|||
or '' |
|||
local lien = jour .. ' ' .. mois .. ' ' .. qualifJour |
|||
if jour == 1 then |
|||
jour = '1<sup>er</sup>' |
|||
lien = '1er ' .. mois .. ' ' .. qualifJour |
|||
end |
|||
-- s'il n'y a pas de lien sur le mois, il sera affiché avec le jour. |
|||
wikiListe.insert( wikiLien( lien, jour ) ) |
|||
wikiListe.insert( wikiLien( lien, jour .. ' '.. mois ) ) |
|||
end |
end |
||
-- s'il n'y a pas de lien sur le mois, il sera affiché avec le jour. |
|||
wikiListe.insert( '[[' .. lien .. '|' .. jour .. ']]' ) |
|||
wikiListe.insert( '[[' .. lien .. '|' .. jour .. ' '.. mois .. ']]' ) |
|||
iso.insert( 1, string.sub( '0' .. gjour, -2 ) ) |
iso.insert( 1, string.sub( '0' .. gjour, -2 ) ) |
||
end |
end |
||
Ligne 320 : | Ligne 509 : | ||
-- le mois |
-- le mois |
||
if mois then |
if mois then |
||
if #wikiListe == 0 and ( annee == nil or decalage > 1 ) then |
|||
local lien |
|||
return mois |
|||
if annee then |
|||
lien = existDate( dataQualificatif, annee, mois ) or existDate( dataCat, annee, mois ) |
|||
if lien == nil and qualificatif and qualifJour == '' then |
|||
-- test nouveau test sans le qualificatif uniquement s'il n'y a pas d'éphémérides pour ce qualificatif. |
|||
lien = existDate( dataLiens[''], annee, mois ) |
|||
end |
|||
end |
end |
||
if |
if args.nolinks then |
||
if decalage < 2 then |
|||
-- s'il y a un lien on retire le lien affichant 'jour mois' pour ajouter '[[mois annee|mois']] |
|||
wikiListe. |
wikiListe.insert( mois ) |
||
end |
|||
wikiListe.insert( '[[' .. lien .. '|' .. mois .. ']]' ) |
|||
else |
else |
||
local lien |
|||
-- sinon on retire le lien affichant 'jour' pour ne garder que le lien 'jour mois' |
|||
if annee then |
|||
wikiListe.remove( #wikiListe - 1 ) |
|||
lien = existDate( dataQualificatif, annee, mois ) or existDate( dataCat, annee, mois ) |
|||
-- s'il n'y avait pas je jour, la liste est vide mais ça ne pose pas de problème |
|||
if lien == nil and qualificatif and qualifJour == '' then |
|||
-- sauf si l'année n'est pas affichée : |
|||
-- test nouveau test sans le qualificatif uniquement s'il n'y a pas d'éphémérides pour ce qualificatif. |
|||
if #wikiListe == 0 and ( annee == nil or decalage > 0 ) then |
|||
lien = existDate( dataLiens[''], annee, mois ) |
|||
return mois |
|||
end |
|||
end |
end |
||
if lien or decalage == 2 then |
|||
-- s'il y a un lien on retire le lien affichant 'jour mois' pour ajouter '[[mois annee|mois']] |
|||
wikiListe.remove() |
|||
if decalage < 2 then |
|||
wikiListe.insert( wikiLien( lien, mois ) ) |
|||
end |
|||
else |
|||
-- sinon on retire le lien affichant 'jour' pour ne garder que le lien 'jour mois' |
|||
wikiListe.remove( #wikiListe - 1 ) |
|||
-- s'il n'y avait pas je jour, la liste est vide mais ça ne pose pas de problème |
|||
-- sauf si l'année n'est pas affichée : |
|||
if #wikiListe == 0 and ( annee == nil or decalage > 0 ) then |
|||
return mois |
|||
end |
|||
end |
|||
end |
|||
if gmois then |
|||
iso.insert( 1, string.sub( '0' .. gmois, -2 ) ) |
|||
end |
end |
||
iso.insert( 1, string.sub( '0' .. gmois, -2 ) ) |
|||
end |
end |
||
if( julien2 ) then |
if( julien2 ) then |
||
wikiListe.insert( julien2 ) |
wikiListe.insert( julien2 ) |
||
end |
end |
||
-- l'année |
-- l'année |
||
if annee |
if annee then |
||
local texteAnnee = annee |
|||
local lien = existDate( dataQualificatif, annee ) or existDate( dataCat, annee ) |
|||
local |
local lien |
||
if annee < 0 then |
if annee < 0 then |
||
local annneeAvJc = 0 - annee |
local annneeAvJc = 0 - annee |
||
Ligne 355 : | Ligne 558 : | ||
local avJC = trim( string.lower( args.avJC or '' ) ) |
local avJC = trim( string.lower( args.avJC or '' ) ) |
||
if args.avJC == 'non' then |
if args.avJC == 'non' then |
||
texteAnnee = annneeAvJc |
|||
else |
else |
||
texteAnnee = annneeAvJc .. ' <abbr class="abbr" title="' |
|||
.. annneeAvJc .. ' avant Jésus-Christ">av. J.-C.</abbr>' |
.. annneeAvJc .. ' avant Jésus-Christ">av. J.-C.</abbr>' |
||
end |
end |
||
end |
|||
iso.insert( 1, tostring( annneeAvJc - 10000 ) ) -- ! avant JC, ce n'est pas une date iso ! Pour un tri correct sur wiki. |
|||
if args.nolinks then -- seulement si on doit l'affichée |
|||
if decalage < 1 then |
|||
wikiListe.insert( texteAnnee ) |
|||
end |
|||
else |
else |
||
lien = existDate( dataQualificatif, annee ) or existDate( dataCat, annee ) or lien or annee |
|||
iso.insert( 1, string.sub( '000' .. annee , -4 ) ) |
|||
if mois and #wikiListe == 0 then |
|||
-- si le mois n'a pas de lien et n'est pas affiché avec le jour, il est affiché avec l'année. |
|||
texteAnnee = mois .. ' ' .. texteAnnee |
|||
end |
|||
if decalage < 1 then -- seulement si on doit l'affichée |
|||
wikiListe.insert( wikiLien( lien, texteAnnee ) ) |
|||
end |
|||
end |
end |
||
lien = lien or annee |
|||
if |
if gannee > 999 then |
||
iso.insert( 1, gannee ) |
|||
-- si le mois n'a pas de lien et n'est pas affiché avec le jour, il est affiché avec l'année. |
|||
elseif gannee > -1 then |
|||
texte = mois .. ' ' .. texte |
|||
iso.insert( 1, string.sub( '000' .. gannee , -4 ) ) |
|||
elseif gannee > -999 then |
|||
-- calendrier grégorien proleptique avec année 0. |
|||
iso.insert( 1, 'U-' .. string.sub( '000' .. ( 0 - gannee ), -4 ) ) |
|||
else |
|||
iso.insert( 1, 'U' .. gannee ) |
|||
end |
end |
||
wikiListe.insert( '[[' .. lien .. '|' .. texte .. ']]' ) |
|||
end |
end |
||
if( julien3 ) then |
if( julien3 ) then |
||
wikiListe.insert( julien3 ) |
wikiListe.insert( julien3 ) |
||
end |
end |
||
-- l'age |
-- l'age |
||
if type( age ) == 'number' and age >= 0 then |
if type( age ) == 'number' and age >= 0 and ( not naissance or age < 120 ) then |
||
if age == 0 then |
if age == 0 then |
||
age = '(moins d\'un an)' |
age = '(moins d\'un an)' |
||
Ligne 383 : | Ligne 604 : | ||
age = '(' .. age .. ' ans)' |
age = '(' .. age .. ' ans)' |
||
end |
end |
||
else |
|||
age = false |
|||
end |
end |
||
Ligne 392 : | Ligne 615 : | ||
local wikiHtml = mw.html.create( '' ) |
local wikiHtml = mw.html.create( '' ) |
||
local dateHtml = wikiHtml:tag( ' |
local dateHtml = wikiHtml:tag( 'time' ) |
||
:addClass( 'date-lien nowrap' ) |
|||
:addClass( 'datasortkey' ) |
|||
:attr( 'data-sort-value', isoTexte ) |
|||
:wikitext( wikiTexte ) |
:wikitext( wikiTexte ) |
||
if wikiTexte:match( ' ' ) then |
|||
dateHtml:addClass( 'nowrap' ) |
|||
end |
|||
if isoTexte ~= wikiTexte then |
|||
dateHtml:attr( 'datetime', isoTexte ) |
|||
end |
|||
if not args.nolinks then |
|||
dateHtml:addClass( 'date-lien' ) |
|||
end |
|||
if naissance then |
if naissance then |
||
dateHtml:addClass( 'bday' ) |
dateHtml:addClass( 'bday' ) |
||
Ligne 412 : | Ligne 641 : | ||
return tostring( wikiHtml ) |
return tostring( wikiHtml ) |
||
end |
end |
||
--- |
|||
-- fonction destinée aux infobox, notamment pour afficher les dates de naissance et de mort |
|||
-- les liens présent dans les dates fournies sont automatiquement supprimées pour gérer les cas ou |
|||
-- le paramètre contient déjà un modèle date. |
|||
-- Paramètres : |
|||
-- 1 : type de date à afficher (naissance / n, mort / m, ou date / d) |
|||
-- 1 : Date ou date de naissance |
|||
-- 2 : Date de mort si type n ou m |
|||
-- qualificatif = suffixe des page de date à lier (exemple : en musique) |
|||
-- nolinks : n'affiche pas de lien |
|||
function fun.dateInfobox( frame ) |
|||
local args = frame.args |
|||
if not args[1] and args[2] then |
|||
return |
|||
end |
|||
local function nettoyageDate( date ) |
|||
-- supprime les liens en ce qui est entre parenthèse à la fin |
|||
date = date:gsub( '%[%[([^%[%]|]*)|?([^%[%]]*)%]%]', function ( l, t ) return trim( t ) or l end ) |
|||
date = date:gsub( '%([^()]+%)$', '' ) |
|||
if date:match( '^%s*[-?/Nn][/Aa.]*%s*$' ) or date:match( 'inconn?ue?' ) then |
|||
return false |
|||
else |
|||
return trim( date ) |
|||
end |
|||
end |
|||
local naissance = args[1]:match( '^n' ) |
|||
local mort = args[1]:match( '^m' ) |
|||
-- S'il y a des liens il y a probablement déjà un modèle date, évitons de l'exècuter une 2e fois |
|||
if mort and args[3] and args[2]:match( '</time>' ) then |
|||
return args[3] |
|||
elseif args[2]:match( '</time>' ) then |
|||
return args[2] |
|||
end |
|||
local nolinks = trim( args.nolinks ) |
|||
local nocat = args.nocat |
|||
local dateN = nettoyageDate( args [2] or '' ) |
|||
local dateM, qualificatif |
|||
if naissance or mort then |
|||
dateM = nettoyageDate( args[3] or '' ) |
|||
qualificatif = args.qualificatif or args[4] |
|||
else |
|||
qualificatif = args.qualificatif or args[3] |
|||
end |
|||
if mort then |
|||
if not dateM then |
|||
return |
|||
end |
|||
local age = '' |
|||
if dateN then |
|||
local t1, tdateN = fun.separationJourMoisAnnee( dateN ) |
|||
local t2, tdateM = fun.separationJourMoisAnnee( dateM ) |
|||
if t1 and t2 then |
|||
local calcul = fun.age( tdateN.annee, tdateN.numMois, tdateN.jour, tdateM.annee, tdateM.numMois, tdateM.jour ) |
|||
if calcul > 1 then |
|||
age = ' (à ' .. calcul .. ' ans)' |
|||
elseif calcul == 1 then |
|||
age = ' (à un an)' |
|||
elseif calcul == 0 then |
|||
age = " (à moins d'un an)" |
|||
end |
|||
end |
|||
end |
|||
return fun.modeleDate{ dateM, qualificatif, mort = '1', nolinks = nolinks, nocat = nocat } .. age |
|||
else |
|||
if not trim( dateN ) then |
|||
return |
|||
end |
|||
if naissance and dateM == nil then |
|||
return fun.modeleDate{ dateN, qualificatif, age = 'oui', naissance='1', nolinks = nolinks, nocat = nocat } |
|||
else |
|||
return fun.modeleDate{ dateN, qualificatif, naissance=naissance, nolinks = nolinks, nocat = nocat } |
|||
end |
|||
end |
|||
end |
|||
--- |
--- |
||
Ligne 421 : | Ligne 732 : | ||
local annee = Outils.notEmpty( args['année'], args.annee, args.year ) |
local annee = Outils.notEmpty( args['année'], args.annee, args.year ) |
||
if annee then |
if annee then |
||
if annee:match( '^%-?%d+$' ) then |
|||
-- si l'année est renseigné, on essaye de trouver le mois |
|||
-- si l'année est correctement renseigné, on essaye de trouver le mois |
|||
local mois = Outils.notEmpty( args.mois, args.month ) |
|||
local mois = Outils.notEmpty( args.mois, args.month ) |
|||
if mois then |
|||
if mois then |
|||
local jour = Outils.notEmpty( args.jour, args.day, args['quantième'] ) |
|||
mois = fun.determinationMois( mois, frame ) or mois |
|||
return fun.modeleDate{ jour, mois:lower(), annee, nolinks=true, nocat=true } |
|||
local jour = Outils.notEmpty( args.jour, args.day, args['quantième'] ) |
|||
if jour then |
|||
-- si le mois est valide on détermine le jour |
|||
jour = tonumber( jour ) or jour -- suppresion des 0 qui trainent |
|||
if jour == 1 or jour == '1er' then |
|||
jour = '<abbr class="abbr" title="Premier">1<sup>er</sup></abbr>' |
|||
end |
|||
return jour .. ' ' .. mois .. ' ' .. annee |
|||
else |
else |
||
return |
return fun.modeleDate{ annee, nolinks=true, nocat=true } |
||
end |
end |
||
else |
else |
||
Ligne 444 : | Ligne 749 : | ||
local date = Outils.validTextArg( args, 'date' ) |
local date = Outils.validTextArg( args, 'date' ) |
||
if date then |
if date then |
||
date = date:lower() |
|||
return '<span class="nowrap">' .. date .. '</span>' |
|||
local t, jma = fun.separationJourMoisAnnee( date ) |
|||
else |
|||
if t then |
|||
args['année'] = jma.annee |
|||
jma.nolinks = true |
|||
jma.nocat = true |
|||
return fun.modeleDate( jma ) |
|||
else |
|||
-- date non reconnue, on essaye Month day, year |
|||
local mois, jour, annee = mw.ustring.match( date, '^([%a]+)%s*(%d%d?),?%s*(%d+)$' ) |
|||
if mois then |
|||
return fun.modeleDate{ jour, mois, annee, nolinks=true, nocat=true } |
|||
end |
|||
end |
|||
return date |
|||
end |
end |
||
end |
end |
||
return '' |
|||
end |
end |
||
Ligne 655 : | Ligne 973 : | ||
--- |
--- |
||
-- calcul du jour julien à partir d'une date du calendrier |
-- calcul du jour julien à partir d'une date du calendrier julien |
||
function fun.julianDayJulian( year, month, day, hour, min, sec ) |
function fun.julianDayJulian( year, month, day, hour, min, sec ) |
||
local julian |
local julian |
Version du 22 avril 2015 à 18:10
Utilisation
Fonctions utilisables depuis un modèle
modeleDate(frame)
– affiche une date, optionnellement avec les liens les plus pertinents (précisions ci-dessous).dateISO(frame)
– similaire à modeleInscriptionDate mais la date est au format aaaa-mm-jj. Paramètres nommés année, mois, jour. Pour respecter l'ISO 8601 qui définit la date uniquement selon le calendrier grégorien, cette fonction ne retourne rien pour les dates avant 1583.dateInfobox(frame)
affiche une date avec les liens pertinents, gère correctement les paramètres contenant déjà un modèle date, ou avec du texte suivant la date (précisions ci-dessous). Prévu pour être utilisé dans les Infobox.dureeInfobox(frame)
affiche la durée entre deux dates, si elle n'est pas déjà incluse. Prévu pour être utilisé dans les Infobox.dateRepublicain(frame)
– affiche une date grégorienne au format républicain (sans liens). Paramètres 1=année, 2=mois, 3=jour.modeleAge(frame)
- retourne l'âge (nombre d'années) depuis une date ou entre deux dates. Paramètres 1=année, 2=mois, 3=jour, 4=année, 5=mois, 6=jour.erreurModuleData()
- retourne un message d'erreur si Module:Date/Data ne se charge pas correctement.checkDataCat(frame)
- retourne une liste de pages annuelle et mensuelle pour faciliter les mises à jour de Date/Data. Paramètres 1=cat, mois=liste de mois si 'oui', alias = liste tous les alias si 'oui'
Fonctions utilisables depuis un autre module
determinationMois( mois )
- à partir d'un nom de mois, de son numéro ou d'une abréviation, retourne, si le mois a bien été trouvé, son nom canonique et son numérodeterminationSaison( saison )
- à partir d'un nom de saison, retourne, si la saison a bien été trouvée, son nom canoniquedo_dayRank(arguments)
- Rang du jour dans l'année. Paramètre arguments = { année, mois, jour } ou { year = année, month = mois, day = jour }isLeapYear(year)
- retourne true si year est une année bissextile dans le calendrier grégorien.toRoman(number)
- transforme number en une chaine le représentant en « chiffres romains ».age( an, mn, jn, ac, mc, jc )
- similaire à modeleAge, mais les paramètres ne sont pas dans une tablejulianDay( year, month, day, hour, minute, second )
- retourne le jour julien de la date transmise, suivant le calendrier grégorien astronomique (avec année 0)julianDayJulian( year, month, day, hour, minute, second )
- retourne le jour julien d'une date du calendrier julien astronomique (avec année 0)julianDayToGregorian( jd )
- retourne trois variables année, mois, jour représentant la date du calendrier grégorien astronomique correspondant à ce jour julien.julianDayToJulian( jd )
- retourne trois variables année, mois, jour représentant la date du calendrier julien correspondant à ce jour julien.julianToGregorian( year, month, day )
- transforme une date du calendrier julien en date du calendrier grégorien.gregorianToJulian( year, month, day )
- transforme une date du calendrier grégorien en date du calendrier julien.
Modules externes dont ce module a besoin pour fonctionner
Date/Data
- Base de donnée permettant de ne pas tester les pages que l'on sait existantes, ou n'existant pas.TableBuilder
– Utilise.insert
et.concat
pour simplifier la syntaxe.
modeleDate( frame )
Paramètres
1
- jour ou vide - numérique, exception possible pour 1er ou 1er.2
- mois ou jour - numérique ou nom français ou anglais, éventuellement une abréviation courante.3
- année ou mois - Un nombre sera considéré comme année. Les années sont considérées comme suivant le calendrier grégorien après le 14 octobre 1582 (sauf si julien = 'oui') et le calendrier julien avant, sans année 0.4
- qualificatif ou année - texte correspondant à une page type « en photographie » pour « 2008 en photographie »5
- qualificatifage
ouâge
- non vide pour afficher l'âge (aucun âge n'est affiché pour les dates dans le futur)julien
- 'oui' pour que la date soit considérée comme suivant le calendrier julien après le 14 octobre 1582. La date grégorienne avec liens est affichée suivie de la date julienne entre parenthèses.compact
- 'oui' pour abréger le nom du mois.avJC
- 'non' pour ne pas afficher 'av. J.-C.' après l'année si elle représente une année avant Jésus-Christ. Utile pour éviter les répétitions.liens
- 'oui' pour forcer l'ajout de liens quand la date ne contient pas de qualificatif.nolinks
- 'oui' pour empêcher l'ajout de liens (a précédence surliens
).
Fonctionnement
- par défaut, le modèle n'ajoute des liens que si un qualificatif a été renseigné.
- le modèle cherche à afficher la date avec des liens vers les pages liées au qualificatif. S'il n'y a pas de page liée au qualificatif un lien sera fait vers la page générale.
- le premier paramètre est vide et le troisième correspond à un mois (texte uniquement), tous les paramètres sont considérés comme décalés et l'année ne sera pas affichée.
- s'il n'y a pas de page spécifique pour ce mois-année, le mois sera affiché lié avec le jour à l'éphéméride. Priorité est donnée à l'éphéméride du qualificatif sur le lien mois-année sans qualificatif.
- le modèle s'aide de la base de donnée Date/Data pour éviter d'utiliser la fonction mw.title (équivalent du parser #ifexist:).
- cette base permet de remplacer le qualificatif par une catégorie plus générique. Si le qualificatif est « en tennis », l'éphéméride et la page mensuelle sera liée au qualificatif « en sport ».
Fonction modeleDate
Motif testé | Chaîne testée | Module | Fonctions coûteuses modèle d'avant / module |
---|---|---|---|
date récente | 14|octobre|2001 | 1 / 0 | |
date ancienne (1700 - 1943), jour =1 | 1|octobre|1842 | 1 / 1 | |
date très ancienne (<1700), jour = 1er | 1|janvier|537 | 1 / 0 | |
qualificatif qui n'est pas dans la base | 14|octobre|2010|en animation asiatique | 4 / 1 | |
date ancienne, qualificatif qui n'est pas dans la base | 14|octobre|1842|en animation asiatique | 4 / 2 | |
avec qualificatif | 14|Octobre|2001|en astronautique | 3 / 0 | |
avec qualificatif avec éphémérides | 14|octobre|2005|dans les chemins de fer | 4 / 0 | |
pas de jour | |octobre|2001 | 1 / 0 | |
pas de jour avec qualificatif | |Octobre|2001|en astronautique | 3 / 0 | |
qualificatif avec page annuelle qui pourrait exister | 14|octobre|2006|en Égypte | 4 / 1 | |
qualificatif avec page mensuelle existante | 14|octobre|2008|en France | 3 / 0 | |
qualificatif avec page mensuelle qui pourrait exister | 14|octobre|2012|en France | 4 / 1 | |
qualificatif avec page annuelle et mensuelle qui pourrait exister | 14|octobre|2012|en économie | 4 / 2 | |
date ancienne avec qualificatif | 14|octobre|1845|en aéronautique | 4 / 1 | |
date négative | 13|octobre|-63 | 1 / 0 | |
date av. J.-C. (orthographe de la page) | 1|octobre|63 av. J.-C. | Erreur Lua à la ligne 256 : attempt to call field 'erreur' (a nil value). | 1 / 0 |
date avJC (orthographe abrégée) | 13|octobre|63 avJC | 1 / 0 | |
date négative, paramètre pour cacher av. J.-C. | 13|octobre|-63|avJC=non | 1 / 0 | |
année invalide | 14|octobre|2001 en sport | Erreur Lua à la ligne 256 : attempt to call field 'erreur' (a nil value). | 1 / 0 |
jour + mois avec majuscule | 14|Octobre|2001 | 1 / 0 | |
mois en abrégé | 14|oct.|2001 | 1 / 0 | |
mois en chiffre | 14|10|2001 | 1 / 0 | |
mois invalide | 14|otcobre|2001 | Erreur Lua à la ligne 256 : attempt to call field 'erreur' (a nil value). | 1 / 0 |
jour invalide | jeudi 14|octobre|2001 | 1 / 0 | |
jour invalide (trop grand pour le mois) | 31|septembre|2001 | Erreur Lua à la ligne 256 : attempt to call field 'erreur' (a nil value). | 1 / 0 |
uniquement l’année | ||2001 | 1 / 0 | |
uniquement l’année avec qualificatif | ||2001|en littérature | 1 / 0 | |
sans année | 14|octobre | 0 / 0 | |
jour uniquement | 14 | Erreur Lua à la ligne 256 : attempt to call field 'erreur' (a nil value). | 0 / 0 |
mois uniquement | |Octobre | Octobre | 0 / 0 |
sans argument | 0 / 0 | ||
date du calendrier julien | 1|octobre|2001|julien=oui | ||
date du calendrier julien (changement de mois) | 25|octobre|2001|julien=oui | ||
date du calendrier julien (changement d'année) | 25|décembre|2001|julien=oui | ||
date de naissance | 14|octobre|2001|age=oui |
Comparaison avec {{date de naissance}}
- les fonctions coûteuses sont les mêmes que celles du modèle Date
- sans l'âge, voir comparaison avec {{Date}}
Motif testé | Chaîne testée | Modèle Date de naissance | Module |
---|---|---|---|
simple | 1|8|2006|âge=oui | ||
avec qualificatif | 1|août|2006|en Suisse|age=oui | ||
date ancienne | 2|1|598|age=oui | ||
l'an dernier | 2|1|2012|age=oui | ||
cette année | 2|1|2013|age=oui | ||
l'an prochain | 2|1|2014|age=oui | ||
sans jour | |8|2006|âge=oui | ||
annee seule | ||2006|âge=oui |
dateInfobox( frame )
Fonction destinée aux infobox, notamment pour afficher les dates de naissance et de mort. Les dates sont affichées avec des liens. Gère les cas où le paramètre contient déjà un modèle date. Le contenu du paramètre situé après la date (par exemple un lieu, une référence) est conservé.
Paramètres
- 1 : type de date à afficher (naissance / n, mort / m, ou date / d)
- 2 : Date ou date de naissance
- 3 : Date de mort si type n ou m
qualificatif
: suffixe des pages de date à lier (exemple : en musique)nolinks
: n'affiche pas de lienpréfixe
: préfixe à afficher s'il y a un jour (par défaut vide)préfixe sans jour
: préfixe à afficher s'il n'y a pas de jour (par défaut vide)
Ces paramètres doivent être directement dans le #invoke appelant la fonction.
Exemples
{{#invoke:Date|dateInfobox|date|13 juillet 1927}}
→{{#invoke:Date|dateInfobox|naissance|13 juillet 1927|}}
→{{#invoke:Date|dateInfobox|naissance|13 juillet 1927|14 mai 2017}}
→{{#invoke:Date|dateInfobox|naissance|30 juin 2017-}}
→ Erreur Lua à la ligne 256 : attempt to call field 'erreur' (a nil value).{{#invoke:Date|dateInfobox|mort|13 juillet 1927|30 juin 2017}}
→ (à 89 ans){{#invoke:Date|dateInfobox|mort||30 juin 2017}}
→{{#invoke:Date|dateInfobox|mort|13 juillet 1927|}}
→{{#invoke:Date|dateInfobox|date|13 juillet 1927| qualificatif = en France}}
→{{#invoke:Date|dateInfobox|date|13 juillet 1927| préfixe = le}}
→{{#invoke:Date|dateInfobox|date|13 juillet 1927| préfixe = le | préfixe sans jour = en}}
→{{#invoke:Date|dateInfobox|date|juillet 1927| préfixe = le}}
→{{#invoke:Date|dateInfobox|date|juillet 1927| préfixe = le | préfixe sans jour = en}}
→{{#invoke:Date|dateInfobox|date|13 juillet [[1927]]}}
→{{#invoke:Date|dateInfobox|date|13 juillet [[1927 en France|1927]]}}
→{{#invoke:Date|dateInfobox|date|{{date|13 juillet 1927|en France}}}}
→
dureeInfobox( frame )
Fonction destinée aux infobox, pour afficher la durée entre deux dates, notamment pour un poste ou une fonction. Gère les cas où la durée est déjà spécifiée dans l'une des valeurs. La durée est préfixée d'un retour à la ligne (<br />
) et écrite en petit (<small>
).
Paramètres
- 1 : Date de début
- 2 : Date de fin (optionnelle, date du jour par défaut)
Ces paramètres doivent être directement dans le #invoke appelant la fonction.
Exemples
{{#invoke:Date|dureeInfobox|8 septembre 2022}}
→ Erreur de script : la fonction « dureeInfobox » n’existe pas.{{#invoke:Date|dureeInfobox|{{date|27 juin 1940-}}|{{date|6 septembre 1940}}}}
→ Erreur de script : la fonction « dureeInfobox » n’existe pas.
Voir aussi : les tests unitaires et ceux du bac à sable.
La documentation de ce module est générée par le modèle {{Documentation module}}.
Elle est incluse depuis sa sous-page de documentation. Veuillez placer les catégories sur cette page-là.
Les éditeurs peuvent travailler dans le bac à sable (modifier).
Voir les statistiques d'appel depuis le wikicode sur l'outil wstat et les appels depuis d'autres modules.
local fun = {}
local TableBuilder = require( 'Module:TableBuilder' )
local Outils = require( 'Module:Outils' )
-- chargement de la base de donnée répertoriant certaines pages existant ou n'existant pas pour éviter les "ifexist".
local dataLiens
local success, resultat = pcall ( mw.loadData, 'Module:Date/Data' )
if success then
dataLiens = resultat
else
-- protection au cas ou le sous module serait mal modifié
dataLiens = { [''] = { mois = { aucun = 1000, tous = { 1773, 2014 } }, } }
end
-- nettoie un paramètre non nommé (vire les espaces au début et à la fin)
-- retourne nil si le texte est vide ou n'est pas du texte. Attention c'est important pour les fonction qui l'utilise.
local trim = Outils.trim
local function ucfirst( str )
return mw.ustring.upper( mw.ustring.sub( str, 1, 1 ) ) .. mw.ustring.sub( str, 2 )
end
-- 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 = 29 },
{ "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 liste_saison = {
{ 'printemps', 'spring', },
{ 'été', 'summer', },
{ 'automne', 'autumn', },
{ 'hiver', 'winter', },
}
-- nom du mois à partir du numéro
function fun.nomDuMois( num )
if type( num ) ~= "number" or num < 1 or num > 12 then
return nil
end
return liste_mois[num][1]
end
---
-- valide que la chaîne passée est un mois valide.
-- retourne le nom complet ou nil si non reconnu
-- si reconnu, retourne aussi le numéro du mois [1-12]
function fun.valideMois( mois )
if type( mois ) ~= "string" then
return nil
end
local m = mw.ustring.lower( mw.text.trim( mois ) )
for i = 1, 12 do
local j = 1
while liste_mois[i][j] ~= nil do
if liste_mois[i][j] == m then
return liste_mois[i][1], i
end
j = j + 1
end
end
-- pas trouvé = return nil
end
---
-- valide que la chaîne passée est un mois valide.
-- retourne le nom complet ou nil si non reconnu
-- si reconnu, retourne aussi le numéro du mois [1-12]
function fun.valideSaison( saison )
if type( saison ) ~= "string" then
return nil
end
local m = mw.ustring.lower( mw.text.trim( saison ) )
for i = 1, 4 do
local j = 1
while liste_saison[i][j] ~= nil do
if liste_saison[i][j] == m then
return liste_saison[i][1]
end
j = j + 1
end
end
-- pas trouvé = return nil
end
---
-- determinationMois trouve le numéro du mois et son nom,
-- à partir de son nom, de son numéro ou d'une expression mathématique.
-- Si le deuxième paramètre est vrai, les nombres supérieur à 12 ou non entiers sont acceptés.
function fun.determinationMois( mois, mod, boucle )
local num, nom
if tonumber( mois ) then
num = math.floor( tonumber( mois ) )
if mod then
-- si le nombre du mois est calculé par une exression, le résultat peut être supérieur à 12, ou inférieur à 1
num = math.fmod( num + 239, 12 ) + 1 -- +239 car fmod(-1) = -1 et non 11
elseif num < 1 or num > 12 then
num = nil
end
elseif trim( mois ) then
nom, num = fun.valideMois( mois )
if nom == nil and boucle == nil then
-- essai de détermination d'un nombre avec le parser #expr de Mediawiki.
-- le paramètre boucle évite de tourner en boucle.
nom, num = fun.determinationMois( mw.getCurrentFrame():callParserFunction( '#expr', mois ), true, true )
end
end
if num and not nom then
nom = liste_mois[num][1]
end
return nom, num
end
-- fonction interne à modeleDate, pour déterminer si on peut se passer de faire un ifexit
local function existDate( dataQualificatif, annee, mois )
local data
if mois then
data = dataQualificatif.mois
else
data = dataQualificatif.annee
end
if type( data ) ~= 'table' then
-- si data n'existe pas c'est que l'on considère qu'il n'y a pas de lien.
return
end
-- le qualificatif est remplacer par celui de la base de donnée, ce qui permet des alias.
local lien = annee .. ' ' .. ( dataQualificatif.qualificatif or '' )
local seul = annee
if mois then
lien = mois .. ' ' .. lien
seul = ucfirst( mois ) .. ' ' .. annee
end
local aucun = tonumber( data.aucun )
if aucun and annee <= aucun then
-- si la l'année est dans la partie 'aucun' on teste s'il y a malgré tout un lien isolé
if type( data.seul ) == 'table' then
for i, v in ipairs( data.seul ) do
if seul == v or seul == tonumber( v ) then
return lien
end
end
end
-- partie aucun et pas de lien => nil
return nil
elseif type( data.tous ) == 'table' then
local tous1, tous2 = tonumber( data.tous[1] ), tonumber( data.tous[2] )
if tous1 and tous2 and annee >= tous1 and annee <= tous2 then
-- l'année est dans la partie 'tous' donc on retourne le lien
return lien
end
end
-- l'annee n'est ni dans la partie aucun, ni dans la partie tous donc il faut tester si la page existe.
cibleLien = mw.title.new( lien )
if cibleLien and cibleLien.exists then
return lien
end
end
---
-- Supprime le jour de la semaine, et "le" avant une date
function fun.nettoyageJour( jour )
if type( jour ) == 'string' then
local nomJour = { '[Ll]undi', '[Mm]ardi', '[Mm]ercredi', '[Jj]eudi', '[Vv]endredi',
'[Ss]amedi', '[Dd]imanche', '^ *[Ll]e' }
local premier = { '<abbr class="abbr" title="Premier" >1<sup>er</sup></abbr>', '1er' }
for i, v in ipairs( nomJour ) do
jour = jour:gsub( v, '' )
end
for i, v in ipairs( premier ) do
jour = jour:gsub( v, '1' )
end
jour = mw.text.trim( jour )
end
return jour
end
---
-- sépare une chaine date en un tabel contenant les champs jour, mois annee.
function fun.separationJourMoisAnnee( date, decalage, args )
date = trim( date )
if date then
local function erreur( periode, valeur )
return false, Outils.erreur( periode .. ' invalide (' .. valeur .. ')' )
end
decalage = decalage or 0
args = args or {}
date = fun.nettoyageJour( date )
local annee = string.match( date, '^%d%d%d%d?$' )
if annee then
return fun.validationJourMoisAnnee{ '', '', annee, args[2 + decalage], decalage = decalage }
end
-- test date au format jj-mm-aaaa
local j, m, a = string.match( date, '^([0-3]?%d)-([^ /-]+)-*(%d*[ AVJCavjc.-]*)$' )
if not m then
-- test date aux formats jj/mm/aaaa ou dd mmm aaaa
j, m, a = string.match( date, '^([0-3]?%d)[ /]+([^ /-]+)[ /]*(-?%d*[ AVJCavjc.-]*)$' )
end
if not m then
-- test date aux formats aaaa-mm-jj, aaaa/mm/jj et aaaa mmm jj
a, m, j = string.match( date, '^(-?%d%d*)[ /-]+([^ /-]+)[ /-]*([0-3]?%d?)$' )
end
if not m then
-- test date aux formats mm/aaaa ou mmm aaaa
m, a = string.match( date, '^([^ /-]+)-?[ /]*(-?%d*[ AVJCavjc.]*)$' )
end
if m then
if decalage < 0 then
decalage = decalage + 2
end
if tonumber( j ) and tonumber( j ) > 31 and tonumber( a ) and tonumber( a ) < 31 then
-- la date est au format aaaa/mm/jj
return fun.validationJourMoisAnnee{ a, m, j, args[2 + decalage], decalage = decalage }
else
return fun.validationJourMoisAnnee{ j, m, a, args[2 + decalage], decalage = decalage }
end
else
return erreur( 'Date', date )
end
else
return true, {}
end
end
---
-- separationJourMoisAnnee prend jusqu'a cinq paramètre et essaie de les séparer en jour, mois, annee et qualificatif
-- la date peut être dans le premier paramètre ou séparée dans les paramètre 1 à 3 ou 2 à 4.
-- Le qualificatif est cherché dans le paramètre suivant.
-- La fonction retourne true suivit d'une table avec la date en paramètres nommé (sans accent sur année)
-- ou false suivit d'un message d'erreur.
function fun.validationJourMoisAnnee( frame, ... )
local args = Outils.extractArgs( frame, ... )
local jour, mois, numMois, annee, qualificatif, erreur
args[1] = tostring( args[1] or args['jour'] or '' )
args[2] = tostring( args[2] or args['mois'] or '' )
args[3] = tostring( args[3] or args['annee'] or args['année'] or '')
args[4] = tostring( args[4] or '' )
local function erreur( periode, valeur )
return false, Outils.erreur( periode .. ' invalide (' .. valeur .. ')' )
end
local decalage = 0
-- si pas de jour mais que args[2] est un mois on décale tout et on
-- n'affiche pas l'année
local arg1, arg2, arg3 = trim( args[1] ), trim( args[2] ), trim( args[3] )
if arg1 == nil and arg2 and (fun.determinationMois( args[3] ) or arg2:match( '[^ /][ /-].*%d%d$' ) ) then
decalage = 1
elseif arg1 == nil and arg2 == nil and arg3 and
( fun.determinationMois( args[4] ) or arg3:match( '[^ /][ /-].*%d%d$' ) ) then
decalage = 2
elseif arg1 and arg1:match( '%d%d%d$' ) then
-- l'année est dans le premier paramètre
decalage = -2
elseif not tonumber( args[3] ) and
tonumber( args[2] ) and tonumber( args[2] ) > 12 and
fun.determinationMois( args[1] )
then
-- le mois est dans le premier paramètre et l'année dans le deuxième
decalage = -1
end
-- on traite l'année
local bannee = args[3 + decalage]
if Outils.notEmpty( bannee ) then
annee = tonumber( bannee )
if annee == nil and type( bannee ) == 'string' then
-- test si l'année contient av. J.-C.
annee = string.match( string.upper( bannee ), '^(%d+)%sAV%.?%s?J%.?%-?C' )
annee = tonumber( annee )
if annee then
annee = 0 - annee
elseif decalage == -2 then
return fun.separationJourMoisAnnee( bannee, decalage, args )
else
return erreur( 'Année', bannee )
end
end
else
annee = nil
end
-- on traite le mois
local bmois = args[2 + decalage]
if Outils.notEmpty( bmois ) then
mois, numMois = fun.determinationMois( bmois )
if mois == nil then
mois = fun.valideSaison( bmois )
if mois == nil then
if annee then
return erreur( 'Mois', bmois )
elseif type( dataLiens[ trim( bmois ) ] ) == 'table' then
-- le deuxième paramètre est un qualificatif, donc la date est dans le premier paramètre
local bjour = args[1 + decalage]
return fun.separationJourMoisAnnee( bjour, decalage, args )
else
return erreur( 'Mois ou qualificatif', bmois )
end
end
else
-- on traite le jour si présent
local bjour = args[1 + decalage]
if Outils.notEmpty( bjour ) then
jour = tonumber( bjour )
if jour == nil then
jour = tonumber( fun.nettoyageJour( bjour ) )
end
if jour == nil then
return erreur( 'Jour', bjour )
end
-- on valide que le jour est correct
if jour < 1 or jour > 31 then
return erreur( 'Jour', bjour )
elseif jour > liste_mois[numMois].nJour then
return erreur( 'Jour', bjour .. bmois )
-- l'année bisextile n'est pas testée pour accepter les dates juliennes.
end
else
-- S'il n'y a pas de jour on regarde si la première lettre du mois est en majuscule
if mw.ustring.match( bmois, '^%u' ) then
-- oui, on passe la première lettre en majuscule
mois = ucfirst( mois )
end
-- s'il n'y a pas d'année non plus on retourne le mois simple
end
end
elseif decalage > -1 then
-- on teste le jour si présent
local bjour = args[1 + decalage]
if Outils.notEmpty( bjour ) then
if annee then
return erreur( 'Mois', 'absent' )
else
bjour = fun.nettoyageJour( bjour )
jour = tonumber( bjour )
if jour then
if jour > 31 or jour < 1 then
annee = jour
jour = nil
else
return erreur( 'date', 'jour seul : ' .. bjour )
end
else
return fun.separationJourMoisAnnee( bjour, decalage, args )
end
end
end
end
-- on traite le champs optionnel
qualificatif = trim( args[4 + decalage] ) or args.qualificatif
local result = {
jour = jour,
mois = mois,
numMois = numMois,
annee = annee,
qualificatif = qualificatif,
decalage = decalage + ( args.decalage or 0 )
}
return true, result
end
---
-- émule le modèle {{m|Date}}.
-- Paramètres :
-- 1 : jour (numéro ou "1er"). optionnel, si absent pas de jour
-- 2 : mois (en toutes lettres)
-- 3 : année (nombre)
-- 4 : optionnel, spécialité de l'année
-- Comportement spécial ("truc à deux balles au lieu d'utiliser un
-- paramètre nommé du genre "sans année=oui"...") : si 1 est vide
-- mais que le reste est complet → on n'affiche pas l'année
function fun.modeleDate( frame )
local args = Outils.extractArgs( frame )
-- séparation des paramètres jour, mois et année si nécessaire
local test, resultat = fun.validationJourMoisAnnee( args )
if not test then
local namespaceCategorisation = { [0] = true, [4] = true, [10] = true, [14] = true, [100] = true }
if namespaceCategorisation[ mw.title.getCurrentTitle().namespace ] and
not Outils.notEmpty( args.nocat ) then
return resultat .. '[[Catégorie:Page utilisant le modèle date avec une syntaxe erronée]]'
else
return resultat
end
end
local annee, mois, numMois, jour = resultat.annee, resultat.mois, resultat.numMois, resultat.jour
local decalage, qualificatif = resultat.decalage, resultat.qualificatif
if ( annee or mois or jour ) == nil then
return
end
-- on traite l'age, naissance et mort
local age = trim( args['âge'] or args['age'] )
age = age and fun.age( annee, numMois, jour )
local naissance = trim( args.naissance )
local mort = trim( args.mort )
-- on traite le calendrier
local gannee, gmois, gjour = annee, numMois, jour -- date suivant le calendrier grégorien pour <time>
local jannee, jmois, jjour = annee, mois, jour -- servira éventuellement à a affiché la date selon le calendrier julien
local julien2, julien3 = nil, nil -- servira éventuellement à a affiché des parenthèses
local julien = trim( string.lower( args.julien or '' ) )
if annee and jour then
local amj = annee * 10000 + numMois * 100 + jour
if amj < 15821014 then
if annee > 0 then
gannee, gmois, gjour = fun.julianToGregorian( annee, numMois, jour )
else
-- calendrier grégorien proleptique avec année 0.
gannee, gmois, gjour = fun.julianToGregorian( annee + 1, numMois, jour )
end
elseif julien == 'oui' then
gannee, gmois, gjour = fun.julianToGregorian( annee, numMois, jour )
annee, mois, jour = gannee, liste_mois[gmois][1], gjour
end
else
if annee and annee < 0 then
gannee = gannee + 1
end
end
-- on génère le résultat
-- Déclarations des variables
local wikiListe = TableBuilder.new() -- reçois le texte affiché pour chaque paramètre
local iso = TableBuilder.new() -- reçois le format date ISO de ce paramètre
local dataQualificatif, dataCat
if not args.nolinks then
dataQualificatif = dataLiens[qualificatif or '']
if type( dataQualificatif ) ~= 'table' then
-- si le qualifiquatif n'est pas dans la base de donnée, on crée une table minimum,
-- qui imposera un test sur l'annee, mais considère qu'il n'y a pas de lien sur le jour ou le mois
dataQualificatif = { qualificatif = ' ' .. qualificatif, annee = { } }
end
dataCat = dataLiens[dataQualificatif.cat]
if type( dataCat ) ~= 'table' or dataCat == dataQualificatif then
dataCat = { qualificatif = '' }
end
end
local function wikiLien( lien, texte )
if lien == texte then
return '[[' .. texte .. ']]'
else
return '[[' .. lien .. '|' .. texte .. ']]'
end
end
-- Date julienne
if jjour ~= jour then
if jjour == 1 then
jjour = '<abbr class="abbr" title="premier">1<sup>er</sup></abbr>'
end
if jannee ~= annee then
julien3 = '(<abbr class=abbr title="selon le calendrier julien">' .. jjour .. ' ' .. jmois .. ' ' .. jannee .. '</abbr>)'
else
julien2 = '(<abbr class=abbr title="selon le calendrier julien">' .. jjour .. ' ' .. jmois .. '</abbr>)'
end
end
-- le jour si présent
local qualifJour = ''
if jour then
local texteJour = jour
if args.nolinks then
if jour == 1 then
jour = '<abbr class="abbr" title="premier">1<sup>er</sup></abbr>'
end
wikiListe.insert( jour )
else
qualifJour = dataQualificatif.jour and dataQualificatif.qualificatif
or dataCat.jour and dataCat.qualificatif
or ''
local lien = jour .. ' ' .. mois .. ' ' .. qualifJour
if jour == 1 then
jour = '1<sup>er</sup>'
lien = '1er ' .. mois .. ' ' .. qualifJour
end
-- s'il n'y a pas de lien sur le mois, il sera affiché avec le jour.
wikiListe.insert( wikiLien( lien, jour ) )
wikiListe.insert( wikiLien( lien, jour .. ' '.. mois ) )
end
iso.insert( 1, string.sub( '0' .. gjour, -2 ) )
end
-- le mois
if mois then
if #wikiListe == 0 and ( annee == nil or decalage > 1 ) then
return mois
end
if args.nolinks then
if decalage < 2 then
wikiListe.insert( mois )
end
else
local lien
if annee then
lien = existDate( dataQualificatif, annee, mois ) or existDate( dataCat, annee, mois )
if lien == nil and qualificatif and qualifJour == '' then
-- test nouveau test sans le qualificatif uniquement s'il n'y a pas d'éphémérides pour ce qualificatif.
lien = existDate( dataLiens[''], annee, mois )
end
end
if lien or decalage == 2 then
-- s'il y a un lien on retire le lien affichant 'jour mois' pour ajouter '[[mois annee|mois']]
wikiListe.remove()
if decalage < 2 then
wikiListe.insert( wikiLien( lien, mois ) )
end
else
-- sinon on retire le lien affichant 'jour' pour ne garder que le lien 'jour mois'
wikiListe.remove( #wikiListe - 1 )
-- s'il n'y avait pas je jour, la liste est vide mais ça ne pose pas de problème
-- sauf si l'année n'est pas affichée :
if #wikiListe == 0 and ( annee == nil or decalage > 0 ) then
return mois
end
end
end
if gmois then
iso.insert( 1, string.sub( '0' .. gmois, -2 ) )
end
end
if( julien2 ) then
wikiListe.insert( julien2 )
end
-- l'année
if annee then
local texteAnnee = annee
local lien
if annee < 0 then
local annneeAvJc = 0 - annee
lien = lien or ( annneeAvJc .. ' av. J.-C.' )
local avJC = trim( string.lower( args.avJC or '' ) )
if args.avJC == 'non' then
texteAnnee = annneeAvJc
else
texteAnnee = annneeAvJc .. ' <abbr class="abbr" title="'
.. annneeAvJc .. ' avant Jésus-Christ">av. J.-C.</abbr>'
end
end
if args.nolinks then -- seulement si on doit l'affichée
if decalage < 1 then
wikiListe.insert( texteAnnee )
end
else
lien = existDate( dataQualificatif, annee ) or existDate( dataCat, annee ) or lien or annee
if mois and #wikiListe == 0 then
-- si le mois n'a pas de lien et n'est pas affiché avec le jour, il est affiché avec l'année.
texteAnnee = mois .. ' ' .. texteAnnee
end
if decalage < 1 then -- seulement si on doit l'affichée
wikiListe.insert( wikiLien( lien, texteAnnee ) )
end
end
if gannee > 999 then
iso.insert( 1, gannee )
elseif gannee > -1 then
iso.insert( 1, string.sub( '000' .. gannee , -4 ) )
elseif gannee > -999 then
-- calendrier grégorien proleptique avec année 0.
iso.insert( 1, 'U-' .. string.sub( '000' .. ( 0 - gannee ), -4 ) )
else
iso.insert( 1, 'U' .. gannee )
end
end
if( julien3 ) then
wikiListe.insert( julien3 )
end
-- l'age
if type( age ) == 'number' and age >= 0 and ( not naissance or age < 120 ) then
if age == 0 then
age = '(moins d\'un an)'
elseif age == 1 then
age = '(1 an)'
else
age = '(' .. age .. ' ans)'
end
else
age = false
end
-- compilation du résultat
local wikiTexte = wikiListe.concat( ' ' )
local isoTexte = iso.concat( '-' )
-- On ajoute un peu de sémantique.
local wikiHtml = mw.html.create( '' )
local dateHtml = wikiHtml:tag( 'time' )
:wikitext( wikiTexte )
if wikiTexte:match( ' ' ) then
dateHtml:addClass( 'nowrap' )
end
if isoTexte ~= wikiTexte then
dateHtml:attr( 'datetime', isoTexte )
end
if not args.nolinks then
dateHtml:addClass( 'date-lien' )
end
if naissance then
dateHtml:addClass( 'bday' )
elseif mort then
dateHtml:addClass( 'dday' )
end
if age then
wikiHtml:wikitext( ' ' )
:tag( 'span' )
:addClass( 'noprint')
:wikitext( age )
:done()
end
return tostring( wikiHtml )
end
---
-- fonction destinée aux infobox, notamment pour afficher les dates de naissance et de mort
-- les liens présent dans les dates fournies sont automatiquement supprimées pour gérer les cas ou
-- le paramètre contient déjà un modèle date.
-- Paramètres :
-- 1 : type de date à afficher (naissance / n, mort / m, ou date / d)
-- 1 : Date ou date de naissance
-- 2 : Date de mort si type n ou m
-- qualificatif = suffixe des page de date à lier (exemple : en musique)
-- nolinks : n'affiche pas de lien
function fun.dateInfobox( frame )
local args = frame.args
if not args[1] and args[2] then
return
end
local function nettoyageDate( date )
-- supprime les liens en ce qui est entre parenthèse à la fin
date = date:gsub( '%[%[([^%[%]|]*)|?([^%[%]]*)%]%]', function ( l, t ) return trim( t ) or l end )
date = date:gsub( '%([^()]+%)$', '' )
if date:match( '^%s*[-?/Nn][/Aa.]*%s*$' ) or date:match( 'inconn?ue?' ) then
return false
else
return trim( date )
end
end
local naissance = args[1]:match( '^n' )
local mort = args[1]:match( '^m' )
-- S'il y a des liens il y a probablement déjà un modèle date, évitons de l'exècuter une 2e fois
if mort and args[3] and args[2]:match( '</time>' ) then
return args[3]
elseif args[2]:match( '</time>' ) then
return args[2]
end
local nolinks = trim( args.nolinks )
local nocat = args.nocat
local dateN = nettoyageDate( args [2] or '' )
local dateM, qualificatif
if naissance or mort then
dateM = nettoyageDate( args[3] or '' )
qualificatif = args.qualificatif or args[4]
else
qualificatif = args.qualificatif or args[3]
end
if mort then
if not dateM then
return
end
local age = ''
if dateN then
local t1, tdateN = fun.separationJourMoisAnnee( dateN )
local t2, tdateM = fun.separationJourMoisAnnee( dateM )
if t1 and t2 then
local calcul = fun.age( tdateN.annee, tdateN.numMois, tdateN.jour, tdateM.annee, tdateM.numMois, tdateM.jour )
if calcul > 1 then
age = ' (à ' .. calcul .. ' ans)'
elseif calcul == 1 then
age = ' (à un an)'
elseif calcul == 0 then
age = " (à moins d'un an)"
end
end
end
return fun.modeleDate{ dateM, qualificatif, mort = '1', nolinks = nolinks, nocat = nocat } .. age
else
if not trim( dateN ) then
return
end
if naissance and dateM == nil then
return fun.modeleDate{ dateN, qualificatif, age = 'oui', naissance='1', nolinks = nolinks, nocat = nocat }
else
return fun.modeleDate{ dateN, qualificatif, naissance=naissance, nolinks = nolinks, nocat = nocat }
end
end
end
---
-- voir émule le modèle:Inscription date
-- la détection des arguments permet d'utilisé la fonction depuis un modèle, depuis invoke, ou depuis une autre fonction.
-- pour facilité l'écriture de lua, annee (sans accent) est accepté lors de l'appel depuis lua.
function fun.inscriptionDate( frame )
local args = Outils.extractArgs( frame )
local annee = Outils.notEmpty( args['année'], args.annee, args.year )
if annee then
if annee:match( '^%-?%d+$' ) then
-- si l'année est correctement renseigné, on essaye de trouver le mois
local mois = Outils.notEmpty( args.mois, args.month )
if mois then
local jour = Outils.notEmpty( args.jour, args.day, args['quantième'] )
return fun.modeleDate{ jour, mois:lower(), annee, nolinks=true, nocat=true }
else
return fun.modeleDate{ annee, nolinks=true, nocat=true }
end
else
return annee
end
else
-- si annee n'est pas précisé, on utilise la paramètre date
local date = Outils.validTextArg( args, 'date' )
if date then
date = date:lower()
local t, jma = fun.separationJourMoisAnnee( date )
if t then
args['année'] = jma.annee
jma.nolinks = true
jma.nocat = true
return fun.modeleDate( jma )
else
-- date non reconnue, on essaye Month day, year
local mois, jour, annee = mw.ustring.match( date, '^([%a]+)%s*(%d%d?),?%s*(%d+)$' )
if mois then
return fun.modeleDate{ jour, mois, annee, nolinks=true, nocat=true }
end
end
return date
end
end
return ''
end
---
-- la fonction dateISO renvoie un date au format aaaa-mm-jj (sans liens)
-- l'année peut être sous la forme 2013 ou [[2013 en litérature|2013]]
-- le mois peut être en lettre ou en chiffres
-- le jour peut être sous la forme '05', '{{1er}}' ou 'vendredi 13'
function fun.dateISO( frame )
local args = Outils.extractArgs( frame )
local annee = Outils.notEmpty( args['année'], args.annee, args.year, args.date )
-- extraction de l'année
if type( annee ) == 'string' then
annee = ( tonumber( annee ) -- match '2013'
or string.match ( annee, '%D(%d%d%d%d)%D' ) -- match '[[2013 en musique|2013]]'
or string.match ( annee, '%D(%d%d%d%d)$' ) -- match '17 septembre 2013'
or string.match ( annee, '^(%d%d%d%d)%D' ) -- match '2013-09-17'
)
end
annee = tonumber( annee )
-- le format de date iso est défini suivant le calendrier grégorien.
-- Avant l'année 1583 la date est calendrier est probablement du calendrier julien,
-- donc autant s'abstenir.
if annee and annee > 1582 then
local mois = Outils.notEmpty( args.mois, args.month )
-- num mois trouve le numéro du mois, qu'il soit numérique ou texte, complet ou abrégé.
local nomMois, numMois = fun.determinationMois( mois )
if numMois then
mois = '-' .. string.sub( '0' .. numMois, -2 )
local jour = Outils.notEmpty( args.jour, args.day, args['quantième'] )
if type( jour ) == 'string' then
jour = tonumber( jour ) or tonumber( string.match ( jour, '%d+') )
end
jour = tonumber( jour )
if jour and jour <= liste_mois[numMois].nJour then
jour = '-' .. string.sub( '0' .. jour, -2 )
return annee .. mois .. jour
else
return annee .. mois
end
else
return tostring( annee )
end
end
end
---
-- Rang du jour dans l'année
-- Usage : do_dayRank{année,mois,jour}
function fun.do_dayRank(arguments)
local yr = tonumber(arguments.year or arguments[1]) or 1
local mt = tonumber(arguments.month or arguments[2]) or 1
local dy = tonumber(arguments.day or arguments[3]) or 1
-- Rangs des premiers des mois
local ranks = {0,31,59,90,120,151,181,212,243,273,304,334}
local rank = (ranks[mt] or 0) + dy - 1
if(fun.isLeapYear(yr) and (mt >= 3)) then
rank = rank+1
end
return rank
end
-- Nombre de jours entre deux années (du 1er janvier au 1er janvier)
-- Suit le calendrier grégorien
function fun.do_daysBetween(arguments)
local yr1 = tonumber(arguments[1]) or 0
local yr2 = tonumber(arguments[2]) or 0
return fun.daysSinceOrigin(yr2) - fun.daysSinceOrigin(yr1)
end
-- Nombre de jours depuis l'année 1 (du 1er janvier au 1er janvier)
function fun.daysSinceOrigin(year)
local yr = year-1
return 365*yr + math.floor(yr/4) - math.floor(yr/100) + math.floor(yr/400)
end
-- Test d'année bissextile (Suit le calendrier grégorien)
function fun.isLeapYear(year)
local yr = tonumber(year) or 1
return (yr%4 == 0) and ((yr%100 ~= 0) or (yr%400 == 0))
end
-- Conversion d'un nombre en chiffres romains
function fun.toRoman(number)
local n = math.floor(number)
local letters = {"I","V","X","L","C","D","M","",""}
local pattern = {"","0","00","000","01","1","10","100","1000","02"}
local result = ""
if(n<=0 or n>=4000) then
result = "---"
else
for i=1,7,2 do
p = pattern[n%10 + 1]
for j=0,2 do
p = string.gsub(p,tostring(j),letters[i+j])
end
result = p .. result
n = math.floor(n/10)
end
end
return result
end
-- Conversion et affichage d'une date dans le calendrier républicain
function fun.dateRepublicain(frame)
local pframe = frame:getParent()
local arguments = pframe.args
return fun.formatRepCal(fun.do_toRepCal(arguments))
end
---
-- Calcul d'une date dans le calendrier républicain
-- On suppose que les années 4n+3 sont sextiles (3, 7, 11...)
function fun.do_toRepCal(arguments)
local yr = tonumber(arguments.year or arguments[1]) or 2000
-- rang absolu du jour demandé, le jour 0 étant le 22 septembre 1792 (1er jour de l'an I)
local repDays = fun.do_dayRank(arguments) + fun.do_daysBetween{1792,yr} - fun.do_dayRank{1792,9,22}
local repYear = math.floor((repDays+731)/365.25) - 1
local repDayRank = repDays - 365*(repYear-1) - math.floor(repYear/4)
local repMonth, repDay = math.floor(repDayRank/30)+1, (repDayRank%30)+1
return {repYear, repMonth, repDay}
end
---
-- Formatage d'une date selon le calendrier républicain
-- Usage : fun.formatRepCal{année,mois,jour}
function fun.formatRepCal(arguments)
local months = {"Vendémiaire","Brumaire","Frimaire","Nivôse","Pluviôse","Ventôse","Germinal","Floréal","Prairial","Messidor","Thermidor","Fructidor"}
local extras = {"de la vertu","du génie","du travail","des récompenses","de l'opinion","de la révolution"}
local result = ""
if(arguments[2] < 13) then
result = result .. tostring(arguments[3]) .. " " .. months[arguments[2]]
else
result = result .. "jour " .. extras[arguments[3]]
end
result = result .. " de l'an " .. fun.toRoman(arguments[1])
return result
end
---
-- Voir Modèle:Âge
-- retourne l'age en fonction de la ou les dates fournies. La valeur retounée est de type 'number'
-- Parammètres :
-- 1, 2, 3 : année, mois jour de naissance (supposé dans le calendrier grégorien)
-- 4, 5, 6 : année, mois, joue du calcul (facultatif, par défaut la date UTC courante).
function fun.age( an, mn, jn, ac, mc, jc )
local an = tonumber( an )
if an == nil then
-- pas de message d'erreur qui risque de faire planter la fonction appelante
-- à elle de gérer ce retour.
return
end
-- les jours et mois sont par défaut égal à 1, pour pouvoir calculer un age même si la date est incompète.
local mn = tonumber( mn ) or 1
local jn = tonumber( jn ) or 1
local today = os.date( '!*t' )
local ac = tonumber( ac ) or today.year
local mc = tonumber( mc ) or today.month
local jc = tonumber( jc ) or today.day
local age = ac - an
if mc < mn or ( mc == mn and jc < jn ) then
age = age - 1
end
return age
end
function fun.modeleAge( frame )
args = frame.getParent().args
local annee = args[1] or args['année']
if annee == nil then
return Outils.erreur( "Il faut au minimum l'année pour calculer un âge" )
end
local age = fun.age (
args[1] or args['année'],
args[2] or args['mois'],
args[3] or args['jour'],
args[4],
args[5],
args[6]
)
if age then
return age
else
return Outils.erreur("les paramètres doivent être des chiffres" )
end
end
---
-- calcul du jour julien à partir d'une date du calendrier grégorien
function fun.julianDay( year, month, day, hour, min, sec )
local julian
julian = math.floor( math.floor( ( year * 12 + month + 57609 ) / 12 - 1 ) * 1461 / 4 )
- math.floor( math.floor( ( year * 12 + month + 57609 ) / 12 - 1 ) / 100 )
+ math.floor( math.floor( ( year * 12 + month + 57609 ) / 12 - 1 ) / 400 )
+ math.floor( ( math.fmod( month + 57609, 12 ) + 4 ) * 153 / 5 )
+ day + ( hour or 12 ) / 24 + ( min or 0 ) / 1440 + ( sec or 0 ) / 86400
- 32167.5
return julian
end
---
-- calcul du jour julien à partir d'une date du calendrier julien
function fun.julianDayJulian( year, month, day, hour, min, sec )
local julian
julian = math.floor( math.floor( ( year * 12 + month + 57609 ) / 12 - 1 ) * 1461 / 4 )
+ math.floor( ( math.fmod( month + 57609, 12 ) + 4 ) * 153 / 5 )
+ day + ( hour or 12 ) / 24 + ( min or 0 ) / 1440 + ( sec or 0 ) / 86400
- 32205.5
return julian
end
---
-- calcul d'une date dans le calendrier grégorien à partir du jour julien
function fun.julianDayToGregorian( julianDay )
local base = math.floor( julianDay + 32044.5 ) -- 1 March -4800 (proleptic Gregorian date)
local nCentury = math.floor( ( base * 4 + 3 ) / 146097 )
local sinceCentury = base - math.floor( nCentury * 146097 / 4 )
local nYear = math.floor( ( sinceCentury * 4 + 3 ) / 1461 )
local sinceYear = sinceCentury - math.floor( nYear * 1461 / 4 )
local nMonth = math.floor( ( sinceYear * 5 + 2 ) / 153 )
local day = sinceYear - math.floor( ( nMonth * 153 + 2 ) / 5 ) + 1
local month = nMonth - math.floor( nMonth / 10 ) * 12 + 3
local year = math.floor( sinceYear / 306 ) + nYear + 100 * nCentury - 4800
return year, month, day
end
---
-- calcul d'une date dans le calendrier julien à partir du jour julien
-- calcul basé sur l'algorythme de la page fr.wikipedia.org/wiki/Jour_julien (1/10/2013)
function fun.julianDayToJulian( julianDay )
local year = math.modf( ( julianDay * 4 - 6884469 ) / 1461 )
local r2 = julianDay - math.modf( ( 1461 * year + 6884472 ) / 4 )
local month = math.modf( ( 5 * r2 + 461 ) / 153 )
local day = r2 - math.modf( ( 153 * month - 457 ) / 5 ) + 1
if month > 12 then
year = year + 1
month = month - 12
end
return year, month, day
end
---
-- calcul d'une date dans le calendrier grégorien à partir d'une date dans le calendrier julien
function fun.julianToGregorian( year, month, day )
return fun.julianDayToGregorian( fun.julianDayJulian( year, month, day ) )
end
---
-- calcul d'une date dans le calendrier julien à partir d'une date dans le calendrier grégorien
function fun.gregorianToJulian( year, month, day )
year = tonumber(year)
if month then month = tonumber(month) else month = 6 end --prend une valeur centrale pour donner un best "guess"
if day then day = tonumber(day) else day = 15 end
return fun.julianDayToJulian( fun.julianDay( year, month, day ) )
end
---
-- erreurModuleData affiche d'un message d'erreur si le Module:Langue/Data n'a pas été chargé correctement,
-- pour la page de discussion de la base de donnée et ceux qui veulent surveiller cette page.
function fun.erreurModuleData()
local success, resultat = pcall ( mw.loadData, 'Module:Date/Data' )
if success == false then
local message = [[<strong class="error">Le chargement du module Date/Data génère une erreur : </strong><br />%s<br />
<span class="error">Cette erreur doit être corrigée au plus vite car des milliers de page ne s'affichent pas correctement</span>
]]
return string.format( message, resultat )
end
end
---
-- checkDataCat génère des liens vers les pages annuelles, mensuelles et d'éphémérides liè aux
-- catégories du Module:Date/Data. La date la plus ancienne dépend de 'aucun' et 'seul[1]'
-- Paramètres :
-- 1 : la catégorie. Il y aura une section par qualificatif de cette catégorie.
-- mois : oui pour avoir les liens vers les pages mensuelles et éphémérides (4 jours dans l'année)
-- alias : pour avoir des lien pour les alias en plus des qualificatif
function fun.checkDataCat( frame )
local category = trim(frame.args[1])
local monthLinks = frame .args.mois == 'oui'
local alias = frame.args.alias == 'oui'
local dataLink = mw.loadData( 'Module:Date/Data' )
local wikiList = TableBuilder.new()
local currentYear = tonumber( os.date( '%Y' ) )
local columns = '<div style="-moz-column-width:5em;-webkit-column-width:5em;column-width:5em;-moz-column-gap:1em;-webkit-column-gap:1em;column-gap:1em;text-align:left;">'
local newSection
if monthLinks then
newSection = '\n\n== %s ==\n\n=== Années ===\n' .. columns
else
newSection ='\n\n== %s ==\n' .. columns
end
for field, dataField in pairs( dataLink ) do
-- boucle sur tous les qualificatif ayant pour catégorie le premier paramère
if dataField.cat == category or ( category == 'cat' and dataField.cat == field ) then
local monthInitialYear, initialYear
-- définition de l'année à partir de laquelle on va tester toutes les année / mois
if dataField.qualificatif == field or ( category == 'cat' and dataField.cat == field ) then
if dataField.annee and dataField.annee.aucun and dataField.annee.aucun < currentYear then
local aucun = ( dataField.annee.seul and dataField.annee.seul[1] ) or dataField.annee.aucun
initialYear = math.min( aucun - math.ceil( (currentYear - aucun) / 4 ), currentYear - 50 )
else
initialYear = currentYear - 50
end
if dataField.mois and tonumber( dataField.mois.aucun ) and ( tonumber( dataField.mois.aucun ) < currentYear ) then
local aucun = dataField.mois.aucun
monthInitialYear = math.min( aucun - math.ceil( (currentYear - aucun) / 4 ), currentYear - 8 )
else
monthInitialYear = currentYear - 8
end
elseif alias then
-- si le paramètre alias est défini on teste aussi tous les alias, sinon ils sont ignorés
initialYear = currentYear - 50
monthInitialYear = currentYear - 8
end
-- création de l'ensembles des liens
if initialYear then
-- ajout de lien vers les pages annuelles de l'année en court + 5 jusqu'à initialYear
wikiList.insert( string.format( newSection, field ) )
local fieldLink = ' ' .. field
if category == 'cat' then
fieldLink = ' ' .. dataField.qualificatif
end
for year = ( currentYear + 5 ), initialYear, -1 do
wikiList.insert( '\n* [[' .. year .. fieldLink ..'|' .. year .. ']]' )
end
wikiList.insert( '\n</div>' )
if monthLinks then
-- insertstion de liens vers les mois de l'année en court + 1 jusqu'à monthInitialYear
wikiList.insert( '\n\n=== Mois ===' )
local month, sep
for year = ( currentYear + 1 ), monthInitialYear, -1 do
wikiList.insert( '\n* ' .. year .. ' : ' )
sep = ' • '
for j = 1, 12 do
month = ucfirst( liste_mois[j][1] ) .. ' '
if j == 12 then sep = ''
end
wikiList.insert( '[[' .. month .. year .. ' ' .. fieldLink .. '|' .. month .. ']]' .. sep )
end
end
-- insertion de quelques date pour tester les éphémérides
wikiList.insert( '\n\n=== Jours ===' )
wikiList.insert( '\n* [[1er janvier ' .. fieldLink .. ']]' )
wikiList.insert( '\n* [[14 mars ' .. fieldLink .. ']]' )
wikiList.insert( '\n* [[22 juin ' .. fieldLink .. ']]' )
wikiList.insert( '\n* [[3 septembre ' .. fieldLink .. ']]' )
end
end
end
end
return table.concat( wikiList )
end
--[[
Cette fonction retourne "CET" ou "CEST" selon que dans la pseudo-timezone en cours
c'est l'heure d'été ou l'heure d'hiver.
Cette fonction n'a de sens a priori que pour des modèles utilisés en Europe
Paramètre optionnel non nommé : "sans lien" : retourne le texte CET/CEST. sinon
retourne ce même texte avec un wikilien vers les articles correspondant
--]]
function fun.CEST(frame)
-- option : ne pas créer de wikilien
local opt = mw.text.trim(frame.args[1] or frame:getParent().args[1] or "")
-- on récupère l'information dans la zone courante
local t = mw.getContentLanguage():formatDate("I", nil, true)
if (t == "1") then -- heure d'été
if (opt == "sans lien") then
return "CEST"
elseif (opt == "décalage") then
return "2"
else
return "[[Heure d'été d'Europe centrale|CEST]]"
end
else -- heure d'hiver (ou autre zone où ça ne s'applique pas)
if (opt == "sans lien") then
return "CET"
elseif (opt == "décalage") then
return "1"
else
return "[[Heure normale d'Europe centrale|CET]]"
end
end
end
return fun