Přeskočit na obsah

Modul:Wikidata/Formatters/time

Tato stránka je zamčena
Z Wikipedie, otevřené encyklopedie

require "Modul:No globals"

local p = {}

local lib = require 'Modul:Wikidata/lib'
local i18n = mw.loadData("Modul:Wikidata/i18n")

local function getPrecision(timevalue, opt_precision)
	return math.min(timevalue.precision, opt_precision or 15)
end

local function okPrecision(timevalue, opt_precision, target_precision)
	if timevalue == 'somevalue' or timevalue == 'novalue' then
		return target_precision < 10
	end
	return target_precision == getPrecision(timevalue, opt_precision)
end

function p.yearDifference(sooner, later)
	local age = later.year - sooner.year
	--[[ pravděpodobně chybně, prozatím skryto
	if age % 4 == 0 and (age % 100 ~= 0 or age % 400 == 0) then
		age = math.floor(age/4)
	end
	]]--
	if sooner.precision > 10 then
		if later.precision > 10 then
			if sooner.month > later.month then
				age = age - 1
			elseif sooner.month == later.month and sooner.day > later.day then
				age = age - 1
			end
			return age, age
		elseif later.precision == 10 then
			if sooner.month == later.month then
				return age - 1, age - 1 .. '–' .. age
			end
			if sooner.month > later.month then
				age = age - 1
			end
			return age, age
		end
	elseif sooner.precision == 10 then
		if later.precision > 9 then
			if sooner.month == later.month then
				return age - 1, age - 1 .. '–' .. age
			end
			if sooner.month > later.month then
				age = age - 1
			end
			return age, age
		end
	end
	return age - 1, age - 1 .. '–' .. age
end

function p.formatTimevalue(timevalue, options)
	local lang = mw.getContentLanguage()
	local precision = getPrecision(timevalue, options.precision)
	local timestring = tostring(timevalue)
	local linked_app = ''
	if not lib.IsOptionTrue(options, 'nolink') then
		linked_app = '-linked'
	end
	local BCE_app = ''
	if timevalue.year < 0 then
		timestring = mw.ustring.sub(timestring, 2)
		BCE_app = '-BCE'
	end

	if precision > 8 then
		local key = ({ [9] = 'year', [10] = 'year-month', [11] = 'year-month-day' })[math.min(precision, 11)]
		local pattern = i18n.date[key .. BCE_app .. linked_app] or i18n.date[key .. BCE_app]
		timestring = lang:formatDate(pattern, timestring)
	elseif precision > 5 then
		local key = ({ [6] = 'millenium', [7] = 'century', [8] = 'decade' })[precision]
		local coef = 10 ^ (9 - precision)
		timestring = mw.getCurrentFrame():preprocess( 
			mw.message.newRawMessage(i18n.date[key .. BCE_app .. linked_app] or i18n.date[key .. BCE_app])
				:params(math.ceil(timevalue.year / coef) * coef) -- numParams vytváří oddělovače
				:plain()
			)
	else
		-- TODO
	end
--	odstraň nuly na začátku (rok < 1000 a > -1000)
	if mw.ustring.find( timestring, '%[%[0+' ) then
		timestring = mw.ustring.gsub( timestring, '%[%[0+', '[[' )
		timestring = mw.ustring.gsub( timestring, '|0+', '|' )
	end
	if lib.IsOptionTrue(options, 'nolink') then
		timestring = mw.ustring.gsub( timestring, '%[%[[^]|]+|', '[[' )
		timestring = mw.ustring.gsub( timestring, '%[%[([^]|]+)%]%]', '%1' )
	end
	return timestring
end

p.formatDateFromTimevalue = p.formatTimevalue

local function formatDateOrSpecial(timevalue, options)
	if timevalue == 'somevalue' then
		return '?'
	else
		return p.formatTimevalue(timevalue, options)
	end
end

function p.formatDateRange(dates, options)
	if not (dates.begin or dates.ending) then
		return error()
	end
	if not dates.begin then
		return mw.ustring.format(i18n.date['end'], formatDateOrSpecial(dates.ending, options))
	end
	if not dates.ending then
		return mw.ustring.format(i18n.date['start'], formatDateOrSpecial(dates.begin, options))
	end

	local begin = formatDateOrSpecial(dates.begin, options)
	local ending = formatDateOrSpecial(dates.ending, options)
	if begin == ending then
		return begin
	end
	local connector = ' – '
	if okPrecision(dates.begin, options.precision, 9) and okPrecision(dates.ending, options.precision, 9) then
		connector = '–'
	end
	return table.concat( { begin, ending }, connector )
end

-- @deprecated
function p.AreDatesSame(first, second, strict)
	return first == second
end

function p.getRawValue(value, options)
	local Time = require 'Modul:Time'
	return Time.newFromWikidataValue(value)
end

function p.formatValue(value, options)
	local timevalue = p.getRawValue(value, options)
	local formatted = p.formatTimevalue(timevalue, options)
	if lib.IsOptionTrue(options, 'birthdate') and timevalue.precision > 8 then
		if #options.entity:getBestStatements('P570') == 0 then
			local Time = require 'Modul:Time'
			local age, age_text = p.yearDifference(timevalue, Time.new(os.date('!*t')))
			formatted = mw.ustring.format('%s (%s)', formatted,
				mw.getCurrentFrame():preprocess( 
					mw.message.newRawMessage(i18n.date.age)
						:params(age_text)
						:numParams(age)
						:plain()
				)
			)
			if age >= 100 then
				formatted = formatted .. lib.category('centenarians-living')
			elseif age < 0 then
				formatted = formatted .. lib.category('failed-age-computing')
			end
		end
	elseif lib.IsOptionTrue(options, 'deathdate') and timevalue.precision > 8 then
		local birthvalue
		for _, statement in ipairs(options.entity:getBestStatements('P569')) do
			if lib.IsSnakValue(statement.mainsnak) then
				local Formatters = require 'Modul:Wikidata/Formatters'
				birthvalue = Formatters.getRawValue(statement.mainsnak)
				break
			end
		end
		if birthvalue and birthvalue.precision > 8 then
			local age, age_text = p.yearDifference(birthvalue, timevalue)
			formatted = mw.ustring.format('%s (%s)', formatted,
				mw.getCurrentFrame():preprocess(
					mw.message.newRawMessage(i18n.date['in-the-age'])
						:params(age_text)
						:numParams(age)
						:plain()
				)
			)
			if age >= 100 then
				formatted = formatted .. lib.category('centenarians')
			end
		end
	end
	return formatted
end

p.formatRawValue = p.formatTimevalue

return p