લખાણ પર જાઓ

વિભાગ:Wikidata/Dates

વિકિપીડિયામાંથી

Documentation for this module may be created at વિભાગ:Wikidata/Dates/doc

local p = {}
local formatDate = require "Module:Complex date"
local tools = require "Module:Wikidata/Tools"
local defaultlang = mw.getCurrentFrame():callParserFunction("int", "lang")

local function splitTimestamp(timestamp, calendar)
	local pattern = "(%W)(%d+)%-(%d+)%-(%d+)"
	local era, year, month, day = timestamp:match(pattern)

	if calendar == 'julian' then
	--todo  year, month, day = formatDate.gregorianToJulian( era .. year, month, day )
	end

	return era, year, month, day
end

local function dateObject(snak, params) --[[
	transforms a Wikibase snak into a simpler table readable by Module:Complex date
		{
		type = "dateobject"
		valuetype = corresponds to the snaktype (value, somevalue or novalue)
		year = number
		month = number
		day = number
		calendar = julian or gregorian
		}
	]]--
	if not params then
		params = {}
	end
	local obj = {type = "dateobject", valuetype = snak.snaktype}
	if snak.snaktype == "value" then
		local value =  tools.getValue(snak)
		obj.era, obj.year, obj.month, obj.day = splitTimestamp(value.time, value.calendar)
		obj.precision = params.precision or value.precision
	end
	return obj
end

local function rangeObject(begin, ending)
	-- object containing one or two dateobject {type = "rangeobject", begin = dateobject, ending = rangeobject}
	local timestamp
	if begin then
		timestamp = begin.timestamp
	elseif ending then
		timestamp = ending.timestamp
	end
	return {begin = begin, ending = ending, timestamp = timestamp, type = 'rangeobject'}
end

-- Functions transforming dateobjects into date strings

local function standardDisplay(obj, precision, lang) -- returns a date in a natural language string
	if obj.valuetype == "somevalue" then
		return formatDate._complex_date("unknown", "", "", "", "", "", "", "", "", lang)
	elseif obj.valuetype == "novalue" then
		return "" -- ?
	end

	if precision >= 11 then
		return formatDate._complex_date("", "", obj.year .. '-' .. obj.month .. '-' .. obj.day, "", "", "" , "", "", "", lang)
	elseif precision == 10 then
		return formatDate._complex_date("", "", obj.year .. '-' .. obj.month, "", "", "" , "", "", "", lang)
	elseif precision == 9 then
		return formatDate._complex_date("", "", obj.year, "", "", "" , "", "", "", lang)
	elseif precision == 8 then
		return formatDate._complex_date("", "",  string.sub(tostring(obj.year), 1, 3) .. '0', "decade", "", "" , "", "", "", lang)
	elseif precision == 7 then
		return formatDate._complex_date("", "", string.sub(tostring(obj.year + 100), 1, 2), "century", "", "" , "", "", "", lang)
	end
end

--- ISO format
local function ISOdate(obj, precision)
	local str = ""
	if obj.valuetype ~= 'value' then
		return nil
	end
	if (precision >= 9) then
		str =  obj.year
	end
	if (precision >= 10) then
		str = str .. "-" .. obj.month
	end
	if (precision >= 11) then
		str = str .. "-" .. obj.day
	end
	return str
end

local function formatDatepoint(obj, params) -- takes in "datobject" and transforms it into a string
	if not obj then
		return nil
	end
	if not params then
		params = {}	
	end
	local lang = params.lang or defaultlang
	local precision
 	if obj.valuetype == "value" then
		precision = math.min(obj.precision, params.precision or 15)
	end

	if params.displayformat == "year" then
		return obj.year
	elseif params.displayformat == "isodate" then
		return ISOdate(obj, precision)
	else
		return standardDisplay(obj, precision, lang)
	end
end

local function formatDaterange(obj, params) --takes "rangeobject" and transforms it into a string
	local begin = formatDatepoint(obj.begin, params)
	local ending = formatDatepoint(obj.ending, params)
	local str = ""
	if begin then
		str = str .. "from " .. begin
	end
	if begin and ending then
		str = str .. " "
	end
	if ending then
		str = str .. "until " .. ending
	end
	return str
end

local function objectToText(obj, params) -- takes any date table and transforms it into a string 
	if obj.type == 'dateobject' then
		return formatDatepoint(obj, params)
	elseif obj.type == 'rangeobject' then
		return formatDaterange(obj, params)
	end
	return nil
end

-- Functions retrieving data from Wikidata

local function getDatefromQualif(statement, qualif)
	if not(tools.hasqualifier(statement, qualif) )then
		return nil
	end
	local v = statement.qualifiers[qualif][1]
	if v.snaktype ~= 'value' then
		return nil -- ?
	end
	return dateObject(v)
end

function p.getDate(statement) -- looks for a date in a statement (either qualifiers or main value) and returns it in the form of a "dateobject" or a "rangeobject"
	-- try to use qualifiers, that can have more accurate values than the main snak
	local period = getDatefromQualif(statement, 'P585') -- retourne un dateobject
	if period then
		return period
	end
	local begin, ending = getDatefromQualif(statement, 'P580'),  getDatefromQualif(statement, 'P582')
	if begin or ending then
		return rangeObject(begin, ending) -- a rangeobject contains two dates
	end
	local begin, ending = getDatefromQualif(statement, 'P1319'),  getDatefromQualif(statement, 'P1326')

	local obj
	if begin or ending then
		return rangeObject(begin, ending) -- should have another parameter stating that these are not the same as with usual qualifs
	end

	-- else, if the main value is a time value, then return it
	local mainsnak = statement.mainsnak
	if mainsnak.datatype ~= 'time' then
		return nil -- if the property datatype is not time, then do not use it
	end
	return dateObject(mainsnak, params)		
end

function p.getFormattedDate(statement, params)
	if not statement then
		return nil
	end
	local str

	local datetable = p.getDate(statement)
	if datetable then
		str = objectToText(datetable, params)
	end	

	local fuzzy = tools.hasqualifier(statement, {"P1480"}, {"Q5727902"}) -- should be moved to the getDate function
	if fuzzy then
		fuzzy = true
	end
	if fuzzy then
		str = formatDate._complex_date("", "circa", str)
	end
	return str
end

function p.formatTimeSnak(snak, params)
	local displayformat = params.displayformat
	if displayformat == 'raw' then
		return snak.datavalue.value.time
	end
	local dateobj = dateObject(snak)
	return objectToText(dateobj, params)
end

return p