Модуль:Wikidata/Даты
Вычисляет и отображает даты рождения и смерти из Викиданных с поддержкой отображения дат по старому стилю, если в Викиданных указана модель пролептического юлианского календаря (d:Q1985786).
local moduleDates = require( "Module:Dates" )
function deepcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[deepcopy(orig_key)] = deepcopy(orig_value)
end
setmetatable(copy, deepcopy(getmetatable(orig)))
else -- number, string, boolean, etc
copy = orig
end
return copy
end
function formatDate( value, infoclass, categoryPrefix, unknownCategory )
if value.unknown == 'novalue' then
return ''
elseif value.unknown == 'unknown' then
local result = "''биллибэт''"
if ( unknownCategory ) then
result = result .. "[[" .. unknownCategory.. "]]"
end
return result
end
-- year only
if value.precision == 9 then
local tCopy = deepcopy( value.structure )
tCopy.day = nil
tCopy.month = nil
return moduleDates.formatWikiImpl(tCopy, tCopy, infoclass, categoryPrefix)
end
-- year and month only
if value.precision == 10 then
local tCopy = deepcopy( value.structure )
tCopy.day = nil
return moduleDates.formatWikiImpl(tCopy, tCopy, infoclass, categoryPrefix)
end
if (value.calendarmodel == 'gregorian') then
return moduleDates.formatWikiImpl( value.structure, value.structure, infocardClass, categoryPrefix )
else
return moduleDates.formatWiki( value.time, infoclass, categoryPrefix )
end
end
-- accepts table of time+precision values
function ageCurrent ( bTable )
local possibleAge = "NYA" -- it meansm "Not Yet Assigned", not what you imagined!
for bKey, bValue in pairs(bTable) do
if ( bValue.unknown ) then
return nil
end
local bStructure = bValue.structure
local bPrecision = bValue.precision
local dStructure = os.date( "*t" )
local calculatedAge = ageImpl ( bStructure, bPrecision, dStructure, 11 )
if ( possibleAge == "NYA" ) then
possibleAge = calculatedAge
else
if ( possibleAge ~= calculatedAge ) then
possibleAge = nil
end
end
end
return possibleAge
end
-- accepts tables of time+precision values
function age ( bTable, dTable )
local possibleAge = "NYA" -- it meansm "Not Yet Assigned", not what you imagined!
for bKey, bValue in pairs( bTable ) do
if ( bValue.unknown ) then
return nil
end
local bStructure = bValue.structure
local bPrecision = bValue.precision
for dKey, dValue in pairs( dTable ) do
if ( dValue.unknown ) then
return nil
end
local dStructure = dValue.structure
local dPrecision = dValue.precision
local calculatedAge = ageImpl ( bStructure, bPrecision, dStructure, dPrecision )
if ( possibleAge == "NYA" ) then
possibleAge = calculatedAge
else
if ( possibleAge ~= calculatedAge ) then
possibleAge = nil
end
end
end
end
return possibleAge
end
function ageImpl ( bStructure, bPrecision, dStructure, dPrecision )
if ( not bStructure or not dStructure or bPrecision < 10 or dPrecision < 10 ) then
return nil
end
if ( bPrecision == 10 or dPrecision == 10 ) then
if ( bStructure.month < dStructure.month ) then
return dStructure.year - bStructure.year
end
if ( bStructure.month == dStructure.month ) then
return nil
end
if ( bStructure.month > dStructure.month ) then
return dStructure.year - bStructure.year - 1
end
end
if ( bStructure.month < dStructure.month ) then
return dStructure.year - bStructure.year
end
if ( bStructure.month == dStructure.month ) then
if ( bStructure.day <= dStructure.day ) then
return dStructure.year - bStructure.year
else
return dStructure.year - bStructure.year - 1
end
end
if ( bStructure.month > dStructure.month ) then
return dStructure.year - bStructure.year - 1
end
return nil
end
-- returns table of time+precision values for specified property
function parseProperty ( propertyName )
local entity = mw.wikibase.getEntityObject()
if not entity or not entity.claims or not entity.claims[propertyName] then
return nil
end
local result = {}
for key, value in pairs( entity.claims[propertyName] ) do
if ( value.mainsnak.snaktype == "value" ) then
-- The calendar model used for saving the data is always the proleptic Gregorian calendar according to ISO 8601.
local timeISO6801 = tostring( value.mainsnak.datavalue.value.time )
local unixtime = moduleDates.parseISO8601( timeISO6801 )
local structure = os.date("*t", unixtime)
local precision = tonumber( value.mainsnak.datavalue.value.precision )
local calendarmodel = 'gregorian';
if (mw.ustring.find(value.mainsnak.datavalue.value.calendarmodel, 'Q1985786', 1, true)) then
calendarmodel = 'julian';
end
local item = { time=unixtime, structure=structure, precision=precision, calendarmodel=calendarmodel }
table.insert ( result, item )
elseif ( value.mainsnak.snaktype == "somevalue" ) then
--unknown
local item = { unknown="unknown" }
table.insert ( result, item )
elseif ( value.mainsnak.snaktype == "novalue" ) then
-- novalue
local item = { unknown="novalue" }
table.insert ( result, item )
end
end
return result
end
-- проверка на совпадающие даты с разной моделью календаря
function checkDupDates( t )
if #t > 1 then
local removed = false;
local j = 1;
-- проверка на совпадающие даты с разной моделью календаря
while (j <= #t) do
local i = 1;
while (i <= #t) do
if i ~= j then
if (os.time(t[j].structure) == os.time(t[i].structure)) then
if ((t[j].calendarmodel == 'gregorian') and
(t[i].calendarmodel == 'julian')) then
removed = true;
break;
else
table.remove(t, i)
end
else
i = i + 1;
end
else
i = i + 1;
end
end
if removed then
removed = false;
table.remove(t, j);
else
j = j+1;
end
end
end
end
local p = {}
function p.dateOfBirth( )
local appendToCategory = mw.title.getCurrentTitle():inNamespace ( 0 )
local bTable = parseProperty ( "p569" )
local dTable = parseProperty ( "p570" )
if not bTable then
return ''
end
checkDupDates(bTable);
local result = ''
for key, value in pairs(bTable) do
if result ~= '' then
result = result .. ' эбэтэр '
end
if ( appendToCategory ) then
result = result .. formatDate(value, 'bday', 'Төрөөбүттэр ', 'Категория:Төрөөбүт күннэрэ быһаарыллыбатах дьон')
else
result = result .. formatDate(value, 'bday', nil, nil )
end
end
if ( not dTable ) then
local age = ageCurrent( bTable )
if ( age ) then
result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'сааһа', 'сааһа', 'сааһа') .. ')</span>'
if ( age > 150 and appendToCategory ) then
result = result .. '[[Категория:Бикипиэдьийэ:Статьи о персоналиях с большим текущим возрастом]]'
end
end
end
return result
end
function p.dateOfDeath( )
local appendToCategory = mw.title.getCurrentTitle():inNamespace ( 0 )
local bTable = parseProperty ( "p569" )
local dTable = parseProperty ( "p570" )
if not dTable then
return ''
end
checkDupDates(dTable);
local result = ''
for key, value in pairs( dTable ) do
if result ~= '' then
result = result .. ' эбэтэр '
end
if ( appendToCategory ) then
result = result .. formatDate(value, 'dday', 'Өлбүттэр ', 'Категория:Өлбүт күннэрэ быһаарыллыбатах дьон')
else
result = result .. formatDate(value, 'dday', nil, nil )
end
end
if ( bTable and dTable ) then
local age = age( bTable, dTable )
if ( age ) then
result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'сааһыгар', 'сааһыгар', 'сааһыгар') .. ')</span>'
if ( age > 150 and appendToCategory ) then
result = result .. '[[Категория:Бикипиэдьийэ:Статьи о персоналиях с большим возрастом во время смерти]]'
end
end
end
return result
end
return p