« Module:Date » : différence entre les versions

De Lagny-sur-Marne Wiki
Aller à la navigation Aller à la recherche
0x010D (discussion | contributions)
liste_mois : ajout des nom de mois en anglais pour compatibilité avec les traduction et avec {{m|MONTHNUMBER}}
0x010D (discussion | contributions)
Ajout fonction determinationMois qui renvoi juillet à artir de Juil, de 07, ou de 5+2
Ligne 78 : Ligne 78 :
     -- pas trouvé
     -- pas trouvé
     return nil
     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.
            num, nom = fun.determinationMois ( frame:callParserFunction('#expr', mois) )
        end
    end
    if num and not nom then
        nom = liste_mois [num][1]
    end
    return nom, num
end
end



Version du 2 août 2013 à 23:46

local fun = {}


-- génère une erreur function fun.erreurDate(texte)

   return '' .. (texte or "aucune erreur indiquée") .. ""

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.
           num, nom = 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 {{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' .. " "
       else
           res = res .. "" .. jour .. " "
       end
   end
   -- le mois
   local tmp = mois .. " " .. annee
   if (fun.ifexist(tmp)) then
       res = res .. "" .. mois .. ""
   else
       if (mois == "mars" or mois == "Mars") then
           res = res .. "" .. mois .. ""
       else
           res = res .. "" .. mois .. ""
       end
   end
   -- si suivi de l'année on ajoute l'espace
   if (decalage == 0) then
       res = res .. " "
   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 .. "" .. 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 = ""
   return res

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]) .. " " .. 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