Modul:Date complexe

Seba na module şıma şenê yû pela dokumani vırazê Modul:Date complexe/dok

-- TODO: améliorer les synergies avec Module:Date (gestion par module:Date de dates sans lien et de "XIe siècle en astronautique"local datemodule = require 'Module:Date'local linguistic -- = require 'Module:Linguistique' -- chargé uniquement si nécessairelocal roman -- = require 'Module:Romain' -- chargé uniquement si nécessairelocal p = {}local numericprecision = { -- convertir les précisions en valeurs numériques = à celles utilisées par Wikidatagigayear = 0,megayear = 3,millenium = 6,century = 7,decade = 8,year = 9,month = 10,day = 11,hour = 12,minute = 13,second = 14,}local function vowelfirst(str)linguistic = require 'Module:Linguistique'return linguistic.vowelfirst(str)endlocal function setprecision(obj, maxprecision)local precisionif type(obj) == "string" thenprecision = tonumber(obj)elseif type(obj) == "number" thenprecision = objelseif type(obj) == "table" thenprecision = tonumber(obj.precision) or numericprecision[obj.precision]endif not precision thenprecision = 0end-- maxprecision, surtout pour données Wikidata quand on veut afficher avec moins de précision que l'input (par exemple afficher seulement l'année)if maxprecision thenmaxprecision = tonumber(maxprecision) or numericprecision[maxprecision]endif maxprecision thenreturn math.min(precision, maxprecision)endreturn precisionendlocal function bigDate(year, precision) -- TODO : gestion de la précisionlocal format = require "Module:Format"local val, unit = 0, ""if year > 999999999 thenunit = " [[giga|G]][[Année julienne|a]]"val = year / 1000000000elseif year > 999999 thenunit = " [[méga|M]][[Année julienne|a]]"val = year / 1000000endval = format.do_formatnum({val})return val .. unitendlocal function milleniumString(millenium, era, hideera)roman =  roman or require 'Module:Romain'local str = roman.toRoman(millenium) .. 'hezar'if era == '-' and (not hideera) thenstr = str .. 'İR 'endreturn strendlocal function centuryString(century, era, hideera)roman =  roman or require 'Module:Romain'local str = 'Seserra' .. roman.toRoman(century) if era == '-' and (not hideera) thenstr = str .. 'İR'endreturn strendlocal function decadeString(decade, era, hideera)local str = ' ' .. decade .. '0'if era == '-' and (not hideera) thenstr = str .. ' İR 'endreturn '[[' .. str .. ']]'endfunction p.simplestring(dateobject, displayformat)-- transforme un object date ponctuel en texte-- les dates de type ISO devraient passer par Module:Date, mais il faut pouvoir désactiver les liensif type(dateobject) == 'string' or type(dateobject) == 'nil' thenreturn dateobjectendif (not dateobject.year) and (not dateobject.month) and dateobject.day then -- si seul le jour est passé, par exemple à cause de removeclutter, le format n'est pas pris en charge par module:Dateif displayformat.precision and numericprecision[displayformat.precision] < 11 thenreturn ''elsereturn tostring(dateobject.day)endendlocal era = dateobject.eraif not displayformat thendisplayformat = {}endlocal linktopic = displayformat.linktopiclocal nolinksif linktopic == '-' thennolinks = trueendlocal strlocal precision = setprecision(dateobject, displayformat.precision)-- formats gérés par ce modulelocal year = tonumber( dateobject.year) or 0if year > 999999 then -- grosses dates pour l'astronomie, la paléontologiereturn bigDate(year, precision)endlocal hideera = displayformat.hideeraif precision == 6 thenlocal millenium = math.floor((year - 1)/1000) + 1str = milleniumString(millenium, era, hideera)elseif precision == 7 thenlocal century = math.floor((year - 1)/100) + 1str = centuryString(century, era, hideera)elseif precision == 8 thenlocal decade = tostring(math.floor(year/10))str = decadeString(decade, era, hideera)endif str thenreturn strend-- formats gérés par Module:Datelocal year = dateobject.yearif year and (era == '-') thenyear = 0 - yearendlocal month, dayif precision > 9 thenmonth = dateobject.monthif precision > 10 thenday = dateobject.dayendendlocal avJC -- équivalent de hideera pour modeleDateif displayformat.hideera thenavJC = 'non'endstr = datemodule.modeleDate{jour = day, mois = month, annee = year, qualificatif = linktopic, nolinks = nolinks, avJC = avJC}return str or ''endlocal function fromToNow(d, datestr, precision) -- retourne "depuis" plutôt que "à partir de" quand c'est pas terminéif (precision >= 11) or (precision == 7) or (precision == 6)  then -- ont dit "à partir du pour les dates avec jour, les siècles, les millénairesif vowelfirst(datestr) then -- suppose l'absence de lien internereturn "depuis l'" .. datestrelsereturn "depuis le " .. datestrendendreturn "depuis " .. datestrendlocal function fromdate(d, displayformat)  -- retourne "à partir de date" en langage natureldisplayformat = displayformat or {}local precision = setprecision(d, displayformat.precision)local datestr = p.simplestring(d, displayformat)if displayformat and displayformat.textformat == 'minimum' thenreturn datestr -- par exemple pour les classements MH, juste afficher la date de débutendif displayformat and displayformat.textformat == 'short' thenreturn datestr .. '&nbsp;&ndash;&nbsp;' -- pour certaines infobox (footballeur par exemple), afficher date de début et un tiretendif p.before ( os.date("!%Y-%m-%dT%TZ"), d) then returnfromToNow(d, datestr, precision)endif (precision >= 11) or (precision == 7) or (precision == 6)  then -- ont dit "à partir du pour les dates avec jour, les siècles, les millénairesreturn 'à partir du ' .. datestrendif (precision == 10) and (vowelfirst(datemodule.determinationMois(d.month))) thenreturn "à partir d'" .. datestrendreturn 'à partir de ' .. datestrendlocal function upto(d, displayformat)  -- retourne "jusqu'à date' en langage natureldisplayformat = displayformat or {}local datestring = p.simplestring(d, displayformat)local precision = setprecision(d, displayformat.precision)if displayformat and displayformat.textformat == 'infobox' thenreturn '&nbsp;&ndash;&nbsp;'.. datestring-- pour certaines infobox (footballeur par exemple), afficher date de début et un tiretendif displayformat and displayformat.textformat == 'short' thenreturn'&nbsp;&ndash;&nbsp;' .. datestring -- pour certaines infobox (footballeur par exemple), afficher date de début et un tiretendif (precision >= 11) or (precision == 7) or (precision == 6) then --on dit "jusqu'au" pour les dates avec jour, et pour les sièclesreturn "jusqu'au " .. datestringelseif (precision > 9) thenreturn "jusqu'à " .. datestringelsereturn "jusqu'en " .. datestringendendlocal function fromuntillong(startstr, endstr, era, precision)-- on dit "du 3 au 14 janvier" mais "de septembe à octobreif precision >= 11 then -- >= dayreturn "du " .. startstr .. " au " ..  endstr .. eraelseif vowelfirst(startstr) thenreturn "d'" .. startstr .. " à ".. endstr .. eraelsereturn "de " .. startstr .. " à " .. endstr .. eraendendendlocal function removeclutter(startpoint, endpoint, precision, displayformat) -- prépare à rendre la date plus jolie : "juin 445 av-JC-juillet 445 av-JC -> juin-juillet 445-av-JC"if (type(startpoint) ~= 'table') or (type(endpoint) ~= 'table') thenreturn startpoint, endpoint, precision, displayformatendlocal era = endpoint.eralocal sameeraif startpoint.era == endpoint.era thensameera = trueendif sameera and (endpoint.year == startpoint.year) thenstartpoint.year = nilif (startpoint.month == endpoint.month) thenstartpoint.month = nilif (startpoint.day == endpoint.day) thenstartpoint.day = nilendendendreturn startpoint, endpoint, era, displayformat, sameeraendfunction p.between(startpoint, endpoint, displayformat)displayformat = displayformat or {}local precision = setprecision(endpoint, displayformat.precision) or 9local startpoint = p.simplestring(startpoint, displayformat)local endpoint = p.simplestring(endpoint, displayformat)if not (startpoint or endpoint) thenreturn nilendif not endpoint thenif precision <= 10 thenreturn "après " ..  startpointelsereturn "après le " ..  startpointendendif not startpoint thenif precision <= 10 thenreturn "avant " ..  endpointelsereturn "avant le " ..  endpointendend -- analyse les paramètres pour éviter les redondances local startpoint, endpoint, era, displayformat, sameera = removeclutter(startpoint, endpoint, precision, displayformat)local startstr, endstr =  p.simplestring(startpoint, displayformat), p.simplestring(endpoint, displayformat)displayformat.hideera = trueif (startstr == '') or (startstr == endstr) thenif (not sameera) thendisplayformat.hideera = false --sinon c'est incompréhensiblereturn p.simplestring(endpoint, displayformat)endreturn endstrend-- pour éviter les tournures répétitives comme  "du 13 septembre 2006 au 18 september 2006"if era == "-" thenera = " av J-C"elseera = ""endif precision <= 10 thenreturn "mabênê " .. startstr .. " ya zi " .. endstr .. " " .. eraelsereturn "entre le " .. startstr .. " et le " .. endstr .. " " .. eraendendlocal function fromuntil(startpoint, endpoint, displayformat)displayformat = displayformat or {}local precision = setprecision(endpoint, displayformat.precision) -- analyse les paramètres pour éviter les redondances local startpoint, endpoint, era, displayformat, sameera = removeclutter(startpoint, endpoint, precision, displayformat)local hideera= displayformat.hideeradisplayformat.hideera = true -- pour les chaînes intermédiaireslocal startstr, endstr =  p.simplestring(startpoint, displayformat), p.simplestring(endpoint, displayformat)if (startstr == '') or (startstr == endstr) thendisplayformat.hideera = hideera -- on va faire une chaîne simple, on reprend donc le format initialement demandéif (not sameera) thendisplayformat.hideera = false --sinon c'est incompréhensibleendreturn p.simplestring(endpoint, displayformat)end-- pour éviter les tournures répétitives comme  "du 13 septembre 2006 au 18 september 2006"if era == '-' thenera = ' İR'elseera = ''endif displayformat.textformat == 'long' thenreturn fromuntillong(startstr, endstr, era, precision)elseif (type(precision) == "number") and (precision > 9) then -- si les date contiennent des mois ou jours, il vaut mieux un espacereturn startstr .. ' -<wbr> ' .. endstr .. eraelsereturn startstr .. '-<wbr>' .. endstr .. eraendendfunction p.fuzzydate(dateobject, displayformat)local str = p.simplestring(dateobject, displayformat)if not str thenreturn nilendreturn "verê " .. strendfunction p.daterange(startpoint, endpoint, displayformat)if startpoint and endpoint thenreturn fromuntil(startpoint, endpoint, displayformat)elseif startpoint thenreturn fromdate(startpoint, displayformat)elseif endpoint thenreturn upto(endpoint, displayformat)elsereturn nilendendfunction p.duration(start, ending)if (not start) or (not ending) thenreturn nil -- ?endreturn datemodule.age(start.year, start.month, start.day, ending.year, ending.month, ending.day)endlocal function splitWDdate(str) -- depuis datavalue.value.time de Wikidata, fonctionnerait aussi en utilisant simplement splitISOlocal pattern = "(%W)(%d+)%-(%d+)%-(%d+)"local era, year, month, day = str:match(pattern)return era, year, month, dayendlocal function splitISO(str)local era, year, month, dayera = string.sub(str, 1, 1)if tonumber(era) thenera = '+'endlocal f = string.gmatch(str, '%d+')year, month, day = f(), f(), f()return era, year, month, dayendfunction p.splitDate(orig, calendar)if not orig thenreturn nilendif type(orig) == 'table' thenreturn origendif type(orig) ~= 'string' thenreturn error("bad datatype for date, string expected, got " .. type(orig))endlocal era, y, m, d = splitWDdate(orig) if not era thenera, y, m, d = splitISO(orig)endy, m, d = tonumber(y or 1), tonumber(m or 1), tonumber(d or 1)return {day = d, month = m, year = y, era = era, type = 'dateobject', calendar = calendar}endfunction p.before(a, b) -- return true if b is before a or if at least one of a or b is missinga = p.splitDate(a) b = p.splitDate(b)if (not a) or (not b) thenreturn trueendlocal order = {'era', 'year', 'month', 'day'}for i, j in pairs(order) doif b[j] < a[j] thenreturn trueelseif b[j] > a[j] thenreturn falseendendreturn trueendreturn p