Dokumentaciju za ovaj modul možete napraviti na stranici Modul:Wikidata/datum/dok

require "Modul:No globals"

local p = {}

local lib = require 'Modul:Wikidata/lib'

local function getTimevalue(value)
	local Time = require 'Modul:TimeWikiD'
	return Time.newFromWikidataValue(value)
end

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

local function yearDifference(sooner, later)
	local age = later.year - sooner.year
	--[[ 
	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

-- fixme: do i18n
function p.formatDateFromTimevalue(timevalue, options)
	local lang = mw.getContentLanguage()
	local precision = getPrecision(timevalue, options.precision)
	local timestring = tostring(timevalue)
	local year_string = 'Y.'
	local BCE = timevalue.year < 0
	if BCE then
		year_string = 'Y." p. n. e.|"Y".&nbsp;p.&nbsp;n.&nbsp;e."'
		timestring = mw.ustring.sub(timestring, 2)
	end

	local century = tonumber(mw.ustring.sub(timestring, 1, 2))
	if tonumber(mw.ustring.sub(timestring, 3, 4)) > 0 then
		century = century + 1
	end
	if precision > 10 then
		timestring = lang:formatDate( 'j. F ' .. year_string, timestring )
	elseif precision == 10 then
		timestring = lang:formatDate( 'F ' .. year_string, timestring )
	elseif precision == 9 then
		timestring = lang:formatDate( year_string, timestring )
	elseif precision == 8 then
		local dec = tonumber(mw.ustring.sub(timestring, 3, 3)) * 10
		if tonumber(mw.ustring.sub(timestring, 4, 4)) > 0 then
			dec = dec + 1
		end
		timestring = mw.ustring.format( '%s.&nbsp;god. %s.&nbsp;vijek', dec, century )
		if BCE then
			timestring = mw.ustring.format( '%s p.&nbsp;n.&nbsp;e.', timestring )
		end
	elseif precision == 7 then
		timestring = mw.ustring.format( '%s.&nbsp;vijek', century )
		if BCE then
			timestring = mw.ustring.format( '%s p.&nbsp;n.&nbsp;e.', timestring )
		end
	elseif precision == 6 then
		local mill = tonumber(mw.ustring.sub(timestring, 1, 1))
		if century % 10 > 0 then
			mill = mill + 1
		end
		timestring = mw.ustring.format( '%s.&nbsp;milenij', mill )
		if BCE then
			timestring = mw.ustring.format( '%s p.&nbsp;n.&nbsp;e.', timestring )
		end
	end
-- (g < 1000 a > -1000)
	if mw.ustring.find( timestring, '%[%[0+' ) then
		timestring = mw.ustring.gsub( timestring, '%[%[0+', '[[' )
		timestring = mw.ustring.gsub( timestring, '|0+', '|' )
	end
	return timestring
end

function p.formatDateFromWikidataValue(value, options)
	return p.formatDateFromTimevalue(getTimevalue(value), options)
end

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

-- fixme: do i18n
function p.formatDateRange(dates, options)
	if dates.begin then
		if dates.ending then
			local connector = ' – '
			if (
				okPrecision(dates.begin, options.precision, 9)
				and okPrecision(dates.ending, options.precision, 9)
			) then
				connector = '–'
			end
			return formatDateOrSpecial(dates.begin, options)
				.. connector .. formatDateOrSpecial(dates.ending, options)
		else
			return 'od ' .. formatDateOrSpecial(dates.begin, options)
		end
	elseif dates.ending then
		return 'do ' .. formatDateOrSpecial(dates.ending, options)
	end
end

function p.formatBirthdate(value, options)
	local timevalue = getTimevalue(value)
	local birthdate = p.formatDateFromTimevalue(timevalue, options)

	local Statements = options.entity:getBestStatements('P570')
	if #Statements > 0 then
		return birthdate
	end

	if timevalue.precision > 8 then
		local Time = require 'Modul:TimeWikiD'
		local age, age_text = yearDifference(timevalue, Time.new(os.date('!*t')))
		birthdate = birthdate .. ' (' .. age_text .. '&nbsp;god.)'
		if age < 0 then
			birthdate = birthdate .. lib.category('failed-age-computing')
		end
		if age >= 100 then
			local Cat = require 'Modul:Kategorije'
			birthdate = birthdate .. Cat.makeCategory('Stogodišnjaci')
		end
	end

	return birthdate
end

function p.formatDeathdate(value, options)
	local deathvalue = getTimevalue(value)
	local deathdate = p.formatDateFromTimevalue(deathvalue, options)

	local birthvalue
	local Formatters = require 'Modul:Wikidata/Formatters'
	local Statements = options.entity:getBestStatements('P569')
	for _, statement in pairs(Statements) do
		if lib.IsSnakValue(statement.mainsnak) then
			birthvalue = Formatters.getRawValue(statement.mainsnak)
			break
		end
	end
	if birthvalue and birthvalue.precision > 8 and deathvalue.precision > 8 then
		local age, age_text = yearDifference(birthvalue, deathvalue)
		deathdate = deathdate .. ' (imao/-la ' .. age_text .. '&nbsp;god.)'
		if age >= 100 then
			local Cat = require 'Modul:Kategorije'
			deathdate = deathdate .. Cat.makeCategory('Stogodišnjaci')
		end
	end

	return deathdate
end

function p.IsSecondLaterThanFirst(first, second)
	if first.year ~= second.year then
		return first.year < second.year
	end
	if first.month ~= second.month then
		return first.month < second.month
	end
	return first.day < second.day
end

-- fixme: metamethod
function p.AreDatesSame(first, second)
	if first.precision == second.precision then
		local precision = first.precision
		if first.year == second.year then
			if precision < 10 then
				return true
			end
			if first.month == second.month then
				if precision < 11 then
					return true
				end
				if first.day == second.day then
					if precision < 12 then
						return true
					end
				end
			end
		end
	end
	return false
end

return p