Module:Date
Εμφάνιση
Τεκμηρίωση module[δημιουργία]
Μπορείτε να συμβάλλετε στη δημιουργία σελίδας τεκμηρίωσης για αυτό το Scribunto module. Οι συντάκτες μπορούν να πειραματίζονται στο αμμοδοχείο (δημιουργία | αντίγραφο) και στις δοκιμαστικές σελίδες (δημιουργία) του module. Παρακαλείστε να προσθέτετε τις κατηγορίες στην υποσελίδα τεκμηρίωσης. Υποσελίδες αυτού του module. |
local fun = {}
local TableBuilder = require( 'Module:TableBuilder' )
local Outils = require( 'Module:Outils' )
-- 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 },
}
-- 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
---
-- determinationMois trouve le numéro du mois et son nom,
-- à partir de son nom, de son numéro ou d'une expression mathématique.
-- l'objet frame est facultatif, mais permet de tester si mois est une expression type '2+3'
function fun.determinationMois( mois, frame )
local num, nom
if tonumber( mois ) then
num = math.floor( math.fmod( tonumber( mois ) - 1, 12 ) ) + 1
elseif type( mois ) == "string" then
nom, num = fun.valideMois( mois )
if nom == nil and frame and frame.callParserFunction then
-- essai de détermination d'un nombre avec le parser #expr de Mediawiki.
-- la fonction s'appelle sans l'objet frame pour ne pas tourner en boucle.
nom, num = fun.determinationMois( frame:callParserFunction( '#expr', mois ) )
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.
mw.log( 'ifexist : ' .. lien )
if mw.title.new( lien ).exists then
return lien
end
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 )
-- 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 = { 1938, 2013 } }, }, parametresPage = { } }
end
local annee, mois, numMois, jour
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
if trim( args[1] ) == nil and fun.valideMois( trim( args[3] ) ) ~= nil then
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 = mw.ustring.match( mw.ustring.upper( bannee ), '^(%d+)%sAV%.?%s?J%.?%-?C' )
annee = tonumber( annee )
if annee then
annee = 0 - annee
else
return Outils.erreur( 'Λανθασμένο έτος (' .. bannee .. ')' )
end
end
else
annee = nil
end
-- on traite le mois
local bmois = args[2 + decalage]
if Outils.notEmpty( bmois ) then
mois, numMois = fun.valideMois( bmois )
if mois == nil then
-- on teste si le mois est fourni sous forme numérique
numMois = tonumber( bmois )
mois = fun.nomDuMois( numMois )
end
if mois == nil then
return Outils.erreur( 'Λανθασμένος μήνας (' .. bmois .. ')' )
else
-- on traite le jour si présent
local bjour = args[1 + decalage]
if Outils.notEmpty( bjour ) then
jour = tonumber( bjour )
if jour == nil and type( bjour ) == 'string' then
bjour = mw.text.trim( bjour )
if bjour == '1er'
or bjour == '<abbr class="abbr" title="Πρώτη" >1<sup>η</sup></abbr>' -- correspond à {{1er}}
then
jour = 1
else
return Outils.erreur( 'Λανθασμένη ημέρα (' .. bjour .. ')' )
end
end
-- on valide que le jour est correct
if jour < 1 or jour > 31 then
return Outils.erreur( 'Λανθασμένη ημέρα (' .. bjour .. ')' )
elseif jour > liste_mois[numMois].nJour then
return Outils.erreur( 'Λανθασμένη ημέρα (' .. bjour .. ' ' .. mois .. ')' )
-- 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
-- else
-- return Outils.erreur("Le mois est obligatoire")
end
-- on traite le champs optionnel
local qualificatif = trim( args[4 + decalage] ) or dataLiens.parametresPage.qualificatif
-- on traite l'age
local age = trim( args['âge'] or args['age'] )
age = age and fun.age( annee, numMois, jour )
-- on traite le calendrier
local gannee, gmois, gjour = annee, numMois, jour -- date suivant le calendrier grégorien pour <time>
local jannee, jmois, jjour, julien = annee, mois, jour -- servira éventuellement à a affiché la date selon le calendrier julien
local julien1, julien2, julien3 = '', '', '' -- servira éventuellement à a affiché des parenthèses
local julien = trim( string.lower( args.julien or dataLiens.parametresPage.julien or '' ) )
if annee and jour then
local amj = annee * 10000 + numMois * 100 + jour
if amj < 15821014 then
gannee, gmois, gjour = fun.julianToGregorian( annee, numMois, jour )
elseif julien == 'oui' then
gannee, gmois, gjour = fun.julianToGregorian( annee, numMois, jour )
annee, numMois, jour = gannee, liste_mois[gmois][1], gjour
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 = 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
local dataCat = dataLiens[dataQualificatif.cat]
if type( dataCat ) ~= 'table' or dataCat == dataQualificatif then
dataCat = { qualificatif = '' }
end
-- Date julienne
if jjour ~= jour then
wikiListe.insert( '<abbr title="selon le calendrier julien" >' .. jjour )
julien1 = '('
if jannee ~= annee then
wikiListe.insert( jmois )
wikiListe.insert( jannee .. '</abbr>' )
julien3 = ')'
else
wikiListe.insert( jmois .. '</abbr>' )
julien2 = ')'
end
end
-- le jour si présent
local qualifJour = ''
if jour then
-- éphémérides du qualificatif, ou de sa catégorie, ou générale.
qualifJour = dataQualificatif.jour and dataQualificatif.qualificatif
or dataCat.jour and dataCat.qualificatif
or ''
local lien = jour .. ' ' .. mois .. ' ' .. qualifJour
if jour == 1 then
jour = '<abbr class="abbr" title="premier">1<sup>η</sup></abbr>'
lien = '1er ' .. mois .. ' ' .. qualifJour
end
-- s'il n'y a pas de lien sur le mois, il sera affiché avec le jour.
wikiListe.insert( julien1 .. '[[' .. lien .. '|' .. jour .. ']]' )
wikiListe.insert( julien1 .. '[[' .. lien .. '|' .. jour .. ' '.. mois .. ']]' .. julien2 )
iso.insert( 1, string.sub( '0' .. gjour, -2 ) )
end
-- le mois
if mois then
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 then
-- s'il y a un lien on retire le lien affichant 'jour mois' pour ajouter '[[mois annee|mois']]
wikiListe.remove()
wikiListe.insert( '[[' .. lien .. '|' .. mois .. ']]' .. julien2 )
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
iso.insert( 1, string.sub( '0' .. gmois, -2 ) )
end
-- l'année
if annee and decalage == 0 then -- seulement si on doit l'affichée
local lien = existDate( dataQualificatif, annee ) or existDate( dataCat, annee )
local texte = annee
if annee < 0 then
local annneeAvJc = 0 - annee
lien = lien or ( annneeAvJc .. ' av. J.-C.' )
local avJC = trim( string.lower( args.avJC or dataLiens.parametresPage.avJC or '' ) )
if args.avJC == 'non' then
texte = annneeAvJc
else
texte = annneeAvJc .. ' <abbr class="abbr" title="'
.. annneeAvJc .. ' μετά Χριστόν">μ.Χ.</abbr>'
end
end
lien = 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.
texte = mois .. ' ' .. texte
end
wikiListe.insert( '[[' .. lien .. '|' .. texte .. ']]' .. julien3 )
iso.insert( 1, string.sub( '000' .. annee , -4 ) )
end
-- l'age
local classAge
if type( age ) == 'number' and age >= 0 then
if age == 0 then
age = '<span class="noprint"> (moins d\'1 an)</span>'
elseif age == 1 then
age = '<span class="noprint"> (1 an)</span>'
else
age = '<span class="noprint"> (' .. age .. ' ans)</span>'
end
classAge = 'class="bday" '
else
age = ''
classAge = ''
end
-- compilation du résultat
local wikiText = wikiListe.concat( ' ' )
-- On ajoute un peu de sémantique. La date doit être dans le calendrier grégorien proleptique
-- ce formatage ne s'applique pas avant J.C.
if wikiText ~= '' and ( gannee == nil or gannee > 0) then
wikiText = '<time '.. classAge .. 'datetime="' .. iso.concat( '-' ) .. '">' .. wikiText .. '</time>'
end
return wikiText .. age
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
-- si l'année est renseigné, on essaye de trouver le mois
local mois = Outils.notEmpty( args.mois, args.month )
if mois then
mois = fun.determinationMois( mois, frame ) or mois
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
return mois .. ' ' .. annee
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
return '<span class="nowrap">' .. date .. '</span>'
else
return ''
end
end
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 julier
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=== Μήνες ===' )
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* [[1η Ιανουαρίου ' .. fieldLink .. ']]' )
wikiList.insert( '\n* [[14 Μαρτίου ' .. fieldLink .. ']]' )
wikiList.insert( '\n* [[22 Ιουνίου ' .. fieldLink .. ']]' )
wikiList.insert( '\n* [[3 Σεπτεμβρίου ' .. fieldLink .. ']]' )
end
end
end
end
return table.concat( wikiList )
end
return fun