Aller au contenu

Module:Wikidata/Dates

Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 6 octobre 2013 à 17:12 et modifiée en dernier par Zolo (discuter | contributions). Elle peut contenir des erreurs, des inexactitudes ou des contenus vandalisés non présents dans la version actuelle.

 Documentation[créer] [purger]
-- sert à récupérer des données usuelles sur Wikidata (les fonctions élémentaires pour l'extraction des données se fait sur Module:Wikidata
-- ce module peut-être appelé par Module:InfoboxBuilder/Helpers qui les met en infobox

local wikidata = require( 'Module:Wikidata')
local formatdate = require( 'Module:Date')

local p = {}

function p.keydate( event ) -- récupère les valeurs contenues dans des qualificatifs, logique assez différente de pour les propriété principales
    local claims = wikidata.getClaims({property = 'p793', targetvalue = event})
    if not claims then
    	return nil
    end
    local datelist = {} -- crée une liste d'objets dateobject et daterange
   
    --[[accepte plusieurs date pour un même événement, mais doivent être dans des déclarations distinctes
 	note: les tables Wikidata on une clé 0 #table n'est donc pas fiable ]]--
    for i, j in pairs(claims) do
        if not j.qualifiers then break end
        local qualif = j.qualifiers
        if qualif['p585'] and not qualif['p585'][1] then
        	table.insert(datelist, p.dateobject(qualif['p585'][0]))
        elseif qualif['p580'] and qualif['p582'] and not qualif['p580'][1] and not qualif['p582'][1] then
        	begin = p.dateobject(qualif['p580'][0])
        	ending = p.dateobject(qualif['p582'][0])
        	table.insert(datelist, p.daterange(begin, ending))
        elseif qualif['p580'] and not qualif['p580'][1] then
        	begin = p.dateobject(qualif['p580'][0])
        	ending = nil
        	table.insert(datelist, p.daterange(begin, ending))
        elseif qualif['p582'] and not qualif['p582'][1] then
        	begin = nil
        	ending = p.dateobject(qualif['p582'][0])
        	table.insert(datelist, p.daterange(begin, ending))
       	end
	end

	table.sort(datelist, function(a,b) return a.timestamp < b.timestamp end)
	for i, j in pairs(datelist) do
		datelist[i] = p.objecttotext(j)
	end
	return mw.text.listToText(datelist)
end

function p.keydatewithfallback(event, fallback)
	first = p.keydate(event)
	if first ~= '' then return first end
	eventlist = {} -- liste tous les événement pertinents (créer une option pour ne retourner que le premier dans la liste ?)
	if not fallback then
		return nil
	end
	if type(fallback) ~= table then
		return error
	end
	for i, j in pairs(fallback) do
		current = p.keydate(j)
		if current ~= '' then
			table.insert(eventlist, wikidata.formatEntityId(j) .. ' : ' .. current)-- indique le nom du l'événement pour éviter les imprécisions
		end
	end
	return mw.text.listToText(eventlist)
end

function p.from(d)  -- retourne "à partir de date" en langage naturel
	if d.year then year = d.year end
	if d.month then month = d.month end
	if d.day then day = d.day end
	
	if day then 
		return 'à partir du ' .. formatdate.modeleDate({day, month, year})
	elseif tonumber(month) == 4 or tonumber(month) == 8  or tonumber(month) == 10 then -- mois commençant par une voyelle
		return 'à partir d\'' .. formatdate.modeleDate({day, month, year})
	else return 
		'à partir de ' .. formatdate.modeleDate({day, month, year})
	end
end

function p.todate(d)  -- retourne "jusqu'à date' en langage naturel
	if d.year then year = d.year end
	if d.month then month = d.month end
	if d.day then day = d.day end

	if day then 
		return 'jusqu\'au ' .. formatdate.modeleDate({day, month, year})
	else return 
		'jusqu\'à' .. formatdate.modeleDate({day, month, year})
	end
end

function p.rangetotext(begin, ending)
	if not begin or not ending then return error end
	
	if begin.day then day1 = begin.day end
	if begin.month then month1 = begin.month end
	if begin.year then year1 = begin.year end

	if ending.day then day2 = ending.day end
	if ending.month then month2 = ending.month end
	if ending.year then year2 = ending.year end
       
   	if year1 == year2 then -- évite de répéter l'année si c'est deux fois la même
   		return formatdate.modeleDate({day1, month1}) .. '-' .. formatdate.modeleDate({day2, month2, year2})
    else
    	return  formatdate.modeleDate({day1, month1, year1}) .. '-' .. formatdate.modeleDate({day2, month2, year2})
    end     
 end
 
 function p.dateobject(orig) --prend une table de date Wikibase, et la retourne sous un format plus manipulable
 	orig = orig.datavalue.value
 	local timestamp = orig.time
	local precision = orig.precision
	local era = '+' -- (after Christ)
	if string.sub(timestamp,1,1) == '-' or  string.sub(timestamp,2,12) == '00000000000' then  -- Before Christ or year 0 (see datamodel)
		era = '-' 
	end 
	local year = nil
	if precision >= 9 then 
		year = string.sub(timestamp, 9, 12)
		if era == '-' then -- remove one Year for BC years because of year 0
			year = tostring(tonumber(year) + 1)
		end
	end
	local month = nil
	if precision >= 10 then
		month = string.sub(timestamp, 14, 15)
	end
	local day = nil
	if precision >= 11 then
		day = string.sub(timestamp, 17, 18)
	end
	local calendar = 'gregorian' -- calendar for display, not storage
	if orig.calendarmodel == 'http://www.wikidata.org/entity/Q1985786' then
		calendar = 'julian'
		year, month, day = formatDate.gregorianToJulian( era .. year, month, day )
	end
	return {type='dateobject', timestamp = timestamp, year=year, month=month, day=day, era= era, calendar=calendar}
end

function p.daterange(date1, date2)
	if date1 then
		if date1.type ~= 'dateobject' then return error end
	end
	if date2 then 
		if date2.type ~= 'dateobject' then return error end
	end
	if date1 and date2 then
		if date1.timestamp > date2.timestamp then return error end -- ne pas inverser les dates, c'est sans doute un erreur
	end
	if date1 then timestamp = date1.timestamp else timestamp = date2.timestamp end
	return {type='daterange', timestamp = timestamp, begin = date1, ending = date2}
end

function p.objecttotext(object)
	if object.type == 'dateobject' then
		return formatdate.modeleDate({object.day, object.month, object.era .. object.year})
	elseif object.type == 'daterange' then
		if object.begin and object.ending then
			return p.rangetotext(object.begin, object.ending)
		elseif object.begin then
			return p.from(object.begin)
		elseif object.ending then
			return p.todate(object.ending)
		end
	else
		return error
	end
end	

function p.duration(range)
	if not range.begin and range.ending then
		return nil
	else 
		a, b = range.begin, range.ending
	end
	return formatdate.age(a.year, a.month, a.day, b.year, b.month, b.day)
end

return p