Aller au contenu

Module:Date

Cette page est protégée.
Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 4 août 2013 à 04:54 et modifiée en dernier par Zebulon84 (discuter | contributions). Elle peut contenir des erreurs, des inexactitudes ou des contenus vandalisés non présents dans la version actuelle.

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

Utilisation

Fonctions 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éro
  • determinationSaison( saison ) - à partir d'un nom de saison, retourne, si la saison a bien été trouvée, son nom canonique
  • do_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 table
  • julianDay( 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 - qualificatif
  • age 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 sur liens).

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. Jour invalide (1er) 1 / 0
date avJC (orthographe abrégée) 13|octobre|63 avJC Année avalide (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 Année avalide (2001 en sport) 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 Mois invalide (10) 1 / 0
mois invalide 14|otcobre|2001 Mois invalide (otcobre) 1 / 0
jour invalide jeudi 14|octobre|2001 Jour invalide (jeudi 14) 1 / 0
jour invalide (trop grand pour le mois) 31|septembre|2001 1 / 0
uniquement l’année ||2001 Le mois est obligatoire 1 / 0
uniquement l’année avec qualificatif ||2001|en littérature Le mois est obligatoire 1 / 0
sans année 14|octobre L'année est obligatoire 0 / 0
jour uniquement 14 Le mois est obligatoire 0 / 0
mois uniquement |Octobre L'année est obligatoire 0 / 0
sans argument Le mois est obligatoire 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 Le mois est obligatoire Mois invalide (8)
avec qualificatif 1|août|2006|en Suisse|age=oui Le mois est obligatoire
date ancienne 2|1|598|age=oui Le mois est obligatoire Mois invalide (1)
l'an dernier 2|1|2012|age=oui Le mois est obligatoire Mois invalide (1)
cette année 2|1|2013|age=oui Le mois est obligatoire Mois invalide (1)
l'an prochain 2|1|2014|age=oui Le mois est obligatoire Mois invalide (1)
sans jour |8|2006|âge=oui Le mois est obligatoire Mois invalide (8)
annee seule ||2006|âge=oui Le mois est obligatoire Le mois est obligatoire


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 lien
  • pré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}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|naissance|13 juillet 1927|}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|naissance|13 juillet 1927|14 mai 2017}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|naissance|30 juin 2017-}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|mort|13 juillet 1927|30 juin 2017}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|mort||30 juin 2017}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|mort|13 juillet 1927|}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|date|13 juillet 1927| qualificatif = en France}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|date|13 juillet 1927| préfixe = le}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|date|13 juillet 1927| préfixe = le | préfixe sans jour = en}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|date|juillet 1927| préfixe = le}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|date|juillet 1927| préfixe = le | préfixe sans jour = en}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|date|13 juillet [[1927]]}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|date|13 juillet [[1927 en France|1927]]}}Erreur de script : la fonction « dateInfobox » n’existe pas.
  • {{#invoke:Date|dateInfobox|date|{{date|13 juillet 1927|en France}}}}Erreur de script : la fonction « dateInfobox » n’existe pas.

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.

local fun = {}


-- génère une erreur
function fun.erreurDate(texte)
    return '<span class="error">' .. (texte or "''aucune erreur indiquée''") .. "</span>"
end

-- nettoie un paramètre non nommé (vire les espaces au début et à la fin)
function fun.nettoie(texte)
    if (texte == nil or texte == "" or type(texte) ~= "string") then
        return ""
    end
    return mw.text.trim(texte)
end

-- fonction "#ifexist", en attendant que mw.title soit intégré et fournisse cette fonctionnalité
function fun.ifexist(page)
    if (page == nil or type(page) ~= "string" or page == "") then
        return false
    end
    return mw.title.new( page ).exist
end


-- Ajoute autant de caractère c que nécessaire à la chaîne str pour arriver à la ongeur length
function fun.prepend(str, c, length)
    local lenstr = mw.ustring.len( str )
    if lenstr < length then
        str = mw.ustring.rep( c, length - lenstr)
    end
    return str
end


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

-- nom du mois à partir du numéro
function fun.nomDuMois(num)
    if (type(num) ~= "number") then
        return nil
    end
    if ((num < 1) or (num > 12)) then
        return nil
    end
    return (liste_mois[num])
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)
    local m = mw.ustring.lower(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

-- trouve le numéro du mois et son nom, qu'il soit fournit par son nom, son numéro ou 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 elle-même mais sans l'objet frame pour ne pas tourner en boucle si ce n'est pas une expression valide.
            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


-- émule le modèle {{m|Date}}. Pas complet.
function fun.modeleDate(frame)
    -- local args = frame:getParent().args
    local args = frame.args
    --[[
    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
    ]]--

    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 ((fun.nettoie(args[1]) == "") and (fun.valideMois(fun.nettoie(args[3])) ~= nil)) then
        decalage = 1
    end

    local bjour = fun.nettoie(args[1+decalage])
    -- on traite le jour si présent
    if (bjour ~= nil and bjour ~= "") then
        local tmp = tonumber(bjour)
        if (tmp == nil) then
            if (bjour == "1er") then
                jour = 1
            else
                return fun.erreurDate("Jour invalide (" .. bjour .. ")")
            end
        else
            jour = tmp
        end
        -- on valide que le jour est correct
        if ((jour < 1) or (jour > 31)) then
            -- note : il faudrait valider le jour en fonction du mois (30/31 ou 28/29)
            return fun.erreurDate("Jour invalide (" .. bjour .. ")")
        end
    else
        jour = nil
    end

    -- on traite le mois
    local bmois = fun.nettoie(args[2+decalage])
    if (bmois == "") then
        return fun.erreurDate("Le mois est obligatoire")
    end
    local mois, num = fun.valideMois(bmois)
    if (mois == nil) then
        return fun.erreurDate("Mois invalide (" .. bmois .. ")")
    end
    -- on regarde si la première lettre est en majuscule
    if (mw.ustring.match(bmois, "^%u") ~= nil) then
        if (jour == nil) then -- interdit si le jour est indiqué
            -- oui, on passe la première lettre en majuscule
            local debut = mw.ustring.match(mois, "^.")
            local fin = mw.ustring.match(mois, "^.(.*)$")
            mois = mw.ustring.upper(debut) .. fin
        end
    end

    -- on traite l'année
    local bannee = fun.nettoie(args[3+decalage])
    if (bannee == "") then
        return fun.erreurDate("L'année est obligatoire")
    end
    local tmp = tonumber(bannee)
    if (tmp == nil) then
        return fun.erreurDate("Année avalide (" .. bannee .. ")")
    end
    annee = tmp

    -- le champs optionnel
    local opt = fun.nettoie(args[4+decalage])
    if (opt == "") then
        opt = nil
    end

    -- on génère le résultat
    local res = ""

    -- le jour si présent
    if (jour ~= nil) then
        if (jour == 1) then
            res = res .. "[[1er " .. mois .. '|<abbr class="abbr" title="premier">1<sup>er</sup></abbr>' .. "]]&nbsp;"
        else
            res = res .. "[[" .. jour .. " " .. mois .. "|" .. jour .. "]]&nbsp;"
        end
    end
    -- le mois
    local tmp = mois .. " " .. annee
    if (fun.ifexist(tmp)) then
        res = res .. "[[" .. tmp .. "|" .. mois .. "]]"
    else
        if (mois == "mars" or mois == "Mars") then
            res = res .. "[[Mars (mois)|" .. mois .. "]]"
        else
            res = res .. "[[" .. mois .. "]]"
        end
    end
    -- si suivi de l'année on ajoute l'espace
    if (decalage == 0) then
        res = res .. "&nbsp;"
    end

    -- l'année
    if (decalage == 0) then -- seulement si on doit l'afficher
        if (opt == nil) then
            tmp = annee
        else
            tmp = annee .. " " .. opt
        end
        if (fun.ifexist(tmp)) then
            res = res .. "[[" .. tmp .. "|" .. annee .. "]]"
        else
            res = res .. "[[" .. annee .. "]]"
        end
    end

    --On ajoute un peu de sémantique
    local iso = fun.prepend(tostring(annee), '0', 4) .. "-" .. fun.prepend(tostring(num), '0', 2)
    if (jour ~= nil) then
        iso = iso .. "-" .. fun.prepend(tostring(jour), '0', 2)
    end
    res = "<time datetime=\"" .. iso .. "\">" .. res .. "</time>"

    return res
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.modeleInscriptionDate(frame)
    local annee, mois, jour
    if frame.getParent then
        annee = frame:getParent().args ['année'] or frame.args ['année'] or frame.args.annee or ''
        mois = frame:getParent().args.mois or frame.args.mois or ''
        jour = frame:getParent().args.jour or frame:getParent().args ['quantième'] or frame.args.jour or ''
    else
        annee = frame ['année'] or frame.annee or ''
        mois = frame.mois or ''
        jour = frame.jour or ''
    end
    if annee == '' then
        -- si annee n'est pas précisé, on utilise la paramètre date
        annee = frame.getParent and (frame:getParent().args.date or frame.args.date) or frame.date or ''
        if annee == '' then 
            return ''
        else 
            return '<span class="nowrap">' .. annee .. '</span>'
        end
    else
        -- si l'année est renseigné, on essaye de trouver le mois
        mois = fun.determinationMois (mois, frame)
        if mois then
            mois = mois .. '&nbsp;'
            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
                jour = jour .. '&nbsp;'
            end
            return jour .. mois .. annee
        else 
            return annee
        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 annee, mois, jour
    if frame.getParent then
        annee = frame:getParent().args ['année'] or frame.args ['année'] or frame.args.annee or ''
        mois = frame:getParent().args.mois or frame.args.mois or ''
        jour = frame:getParent().args.jour or frame:getParent().args ['quantième'] or frame.args.jour or ''
    else
        annee = frame ['année'] or frame.annee or ''
        mois = frame.mois or ''
        jour = frame.jour or ''
    end
    annee = tonumber ( annee ) or string.match ( annee, '%D(-? ?%d?%d?%d%d)%D')
    if annee then
        local nommois, numMois = fun.determinationMois( mois, frame )
        if numMois then
            if numMois < 10 then
                mois = '-0' .. numMois
            else
                mois = '-' .. numMois
            end
            local numJour = tonumber(jour) or tonumber( string.match ( jour, '%D?(%d?%d)%D?') )
            if numJour then
                if numJour < 10 then
                    jour = '-0' .. numJour
                else
                    jour = '-' .. numJour
                end
            else
                jour = ''
            end
        else
            mois = ''
            jour = ''
        end
        return annee .. mois .. jour
    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
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]) .. "&nbsp;" .. months[arguments[2]]
	else
		result = result .. "jour " .. extras[arguments[3]]
	end
	result = result .. " de l'an " .. fun.toRoman(arguments[1])
	return result
end

return fun