Модуль:Wikidata/date:версиослэн висъяськемзы

Пушкесэз ӵушемын Пушкесэз ватсамын
Новая страница: «local moduleDates = require( "Module:Dates" ) local moduleWikidata = require( "Module:Wikidata" ) function deepcopy(orig) local orig_type = type(orig) lo…»
 
обновление из ru:Модуль:Wikidata/date
1-тӥ чур:
--settings
local categoryUnknownBirthDate = '[[Категория:Персоналии, чья дата рождения не установлена]]';
local categoryUnknownDeathDate = '[[Категория:Персоналии, чья дата смерти не установлена]]';
local categoryBigCurrentAge = '[[Категория:Википедия:Статьи о персоналиях с большим текущим возрастом]]'
-- local categoryBigDeathAge = '[[Категория:Википедия:Статьи о персоналиях с большим возрастом во время смерти]]'
local categoryBiographiesOfLivingPersons = '[[Категория:Википедия:Биографии современников]]'
 
local moduleDates = require( "Module:Dates" )
local moduleWikidata = require( "Module:Wikidata" )
Гож 78 ⟶ 85:
if ( not bStructure or not dStructure or bPrecision < 10 or dPrecision < 10 ) then
return nil
end
 
local shift = 0;
if ( bStructure.year < 0 and dStructure.year > 0 ) then
shift = -1;
end
 
if ( bPrecision == 10 or dPrecision == 10 ) then
if ( bStructure.month < dStructure.month ) then
return dStructure.year - bStructure.year + shift
end
if ( bStructure.month == dStructure.month ) then
Гож 88 ⟶ 100:
end
if ( bStructure.month > dStructure.month ) then
return dStructure.year - bStructure.year - 1 + shift
end
end
if ( bStructure.month < dStructure.month ) then
return dStructure.year - bStructure.year + shift
end
if ( bStructure.month == dStructure.month ) then
if ( bStructure.day <= dStructure.day ) then
return dStructure.year - bStructure.year + shift
else
return dStructure.year - bStructure.year - 1 + shift
end
end
if ( bStructure.month > dStructure.month ) then
return dStructure.year - bStructure.year - 1 + shift
end
 
Гож 110 ⟶ 122:
 
-- returns table of time+precision values for specified property
function parseProperty ( context, propertyNameoptions, propertyId )
localif claims( =not context.selectClaims ) then error( propertyName'context not specified'); end;
if ( not options ) then error( 'options not specified'); end;
if ( not options.entity ) then error( 'options.entity is missing'); end;
if ( not propertyId ) then error( 'propertyId not specified'); end;
 
local claims = context.selectClaims( options, propertyId );
if not claims then
return nil
Гож 126 ⟶ 143:
if ( claim.mainsnak.snaktype == "value" ) then
-- The calendar model used for saving the data is always the proleptic Gregorian calendar according to ISO 8601.
local timeISO6801timeISO8601 = string.gsub( string.gsub( tostring( claim.mainsnak.datavalue.value.time ), '-00%-', '-01-' ), '-00T', '-01T' )
local unixtime = moduleDates.parseISO8601( timeISO6801timeISO8601 )
local structure = os.date("*t", unixtime)
local precision = tonumber( claim.mainsnak.datavalue.value.precision )
Гож 174 ⟶ 191:
end
end
end
 
-- returns first qualifier of specified propertyId
function getQualifierDataValue( statement, qualifierPropertyId )
if ( statement.qualifiers
and statement.qualifiers[qualifierPropertyId] ) then
local qualifiers = statement.qualifiers[qualifierPropertyId];
for _, qualifier in ipairs( qualifiers ) do
if (qualifier.datavalue) then
return qualifier.datavalue;
end
end
end
return nil;
end
 
local p = {}
 
function p.formatDateOfBirthClaim( context, options, statement )
if ( not context.options[ ) then error( 'conjunction']context =not specified'&#32);или&#32 end;'
if ( not options ) then error( 'options not specified'); end;
context.options['value-module'] = 'Wikidata/date'
if ( not options.entity ) then error( 'options.entity is missing'); end;
context.options['value-function'] = 'formatBirthDate'
if ( not statement ) then error( 'statement not specified'); end;
context.options['somevalue'] = '\'\'неизвестно\'\'[[К:Персоналии, чья дата рождения не установлена]]'
 
local result = context.formatStatementDefault( context, statement );
if ( statement.mainsnak.snaktype == 'somevalue' ) then
local qNotSoonerThan = getQualifierDataValue( statement, 'P1319' );
local qNotLaterThan = getQualifierDataValue( statement, 'P1326' );
if ( qNotSoonerThan or qNotLaterThan ) then
local results = {};
if ( qNotSoonerThan ) then
table.insert( results, 'не&nbsp;ранее&nbsp;' .. formatDateImpl( qNotSoonerThan.value, {}, nil, nil ) );
end
if ( qNotLaterThan ) then
table.insert( results, 'не&nbsp;позднее&nbsp;' .. formatDateImpl( qNotLaterThan.value, {}, nil, nil ) );
end
return mw.text.listToText( results, ' и ' , ' и ' ) .. categoryUnknownBirthDate;
end
end
 
options['conjunction'] = '&#32;или&#32;';
options['value-module'] = 'Wikidata/date';
options['value-function'] = 'formatBirthDate';
options.i18n.somevalue = '\'\'неизвестно\'\'' .. categoryUnknownBirthDate;
options.i18n.circa = '<span style="border-bottom: 1px dotted; cursor: help;" title="около">ок. </span>';
local result = context.formatStatementDefault( context, options, statement );
 
local bTable = { parseClaim( statement ) };
local dTable = parseProperty ( context, "p570"options, 'P570' )
 
if ( bTable and 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 not context.options.nocat ) then
if ( age > 115 ) then
result = result .. '[[К:Википедия:Статьи о персоналиях с большим текущим возрастом]]'
result = result .. categoryBigCurrentAge;
end
else
result = result .. categoryBiographiesOfLivingPersons;
end
end
end
end
Гож 201 ⟶ 257:
end
 
function p.formatDateOfDeathClaim( context, options, statement )
if ( not context.options[ ) then error( 'conjunction']context =not specified'&#32);или&#32 end;'
if ( not options ) then error( 'options not specified'); end;
context.options['value-module'] = 'Wikidata/date'
if ( not options.entity ) then error( 'options.entity is missing'); end;
context.options['value-function'] = 'formatDeathDate'
if ( not statement ) then error( 'statement not specified'); end;
context.options['somevalue'] = '\'\'неизвестно\'\'[[К:Персоналии, чья дата смерти не установлена]]'
 
local result = context.formatStatementDefault( context, statement );
if ( statement.mainsnak.snaktype == 'somevalue' ) then
local qNotSoonerThan = getQualifierDataValue( statement, 'P1319' );
local qNotLaterThan = getQualifierDataValue( statement, 'P1326' );
if ( qNotSoonerThan or qNotLaterThan ) then
local results = {};
if ( qNotSoonerThan ) then
table.insert( results, 'не&nbsp;ранее&nbsp;' .. formatDateImpl( qNotSoonerThan.value, {}, nil, nil ) );
end
if ( qNotLaterThan ) then
table.insert( results, 'не&nbsp;позднее&nbsp;' .. formatDateImpl( qNotLaterThan.value, {}, nil, nil ) );
end
return mw.text.listToText( results, ' и ' , ' и ' ) .. categoryUnknownDeathDate;
end
end
 
options['conjunction'] = '&#32;или&#32;';
options['value-module'] = 'Wikidata/date';
options['value-function'] = 'formatDeathDate';
options.i18n.somevalue = '\'\'неизвестно\'\'' .. categoryUnknownDeathDate;
options.i18n.circa = '<span style="border-bottom: 1px dotted; cursor: help;" title="около">ок. </span>';
local result = context.formatStatementDefault( context, options, statement );
 
local bTable = parseProperty ( context, "p569"options, 'P569' )
local dTable = { parseClaim( statement ) };
 
Гож 214 ⟶ 291:
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 not context.options.nocat ) then
result = result .. '[[К:Википедия:Статьи о персоналиях с большим возрастом во время смерти]]'
end
end
end
Гож 225 ⟶ 299:
 
-- Reentry point for Wikidata Snak formatting
function p.formatBirthDate( valuecontext, options, value )
if ( not context ) then error( 'context not specified'); end;
if ( not options ) then error( 'options not specified'); end;
if ( not value ) then error( 'value not specified'); end;
if ( options.nocat ) then
return formatDateImpl( value, options, 'bday', nil )
else
return formatDateImpl( value, options, 'bday', 'Родившиеся ' )
end
end
 
-- Reentry point for Wikidata Snak formatting
function p.formatDeathDate( valuecontext, options, value )
if ( not context ) then error( 'context not specified'); end;
if ( not options ) then error( 'options not specified'); end;
if ( not value ) then error( 'value not specified'); end;
 
if ( options.nocat ) then
return formatDateImpl( value, options, 'dday', nil )
else
return formatDateImpl( value, options, 'dday', 'Умершие ' )
end
end
 
-- Reentry point for Wikidata Snak formatting -- default one
function p.formatDate( valuecontext, options, value )
if ( not context ) then error( 'context not specified'); end;
if ( not options ) then error( 'options not specified'); end;
if ( not value ) then error( 'value not specified'); end;
 
local microformatClass = options.microfortmat or nil;
if ( options.nocat ) then
Гож 254 ⟶ 340:
 
function formatDateImpl( value, options, microformatClass, categoryPrefix )
if ( not value ) then error( 'value not specified'); end;
if ( not options ) then error( 'options not specified'); end;
 
-- The calendar model used for saving the data is always the proleptic Gregorian calendar according to ISO 8601.
local timeISO6801timeISO8601 = string.gsub( string.gsub( tostring( value.time ), '-00%-', '-01-' ), '-00T', '-01T' )
local unixtime = moduleDates.parseISO8601( timeISO6801timeISO8601 )
 
local structure = os.date("*t", unixtime)
local precision = tonumber( value.precision )
if precision == 6 then
return formatMillenium(structure, categoryPrefix)
end
if precision == 7 then
return moduleDates.formatCentury(structure, categoryPrefix)
end
 
if precision == 8 then
return moduleDates.formatDecade(structure, categoryPrefix)
end
 
Гож 291 ⟶ 383:
return moduleDates.formatWikiImpl( structure, structure, microformatClass, categoryPrefix )
else
return moduleDatesp.formatWikiformatAsJulian( unixtime, infoclass, categoryPrefix )
end
end
 
function formatDecade( time, categoryNamePrefix )
if ( time.year < 0 ) then
local year = math.floor( math.abs(time.year) / 10 ) * 10;
if ( categoryNamePrefix ) then
return year .. '-е до н. э.[[К:' .. categoryNamePrefix .. ' в ' .. year .. '-е годы до н. э.]]';
else
return '' .. year .. ' до н. э.';
end
else
local year = math.floor( time.year / 10 ) * 10;
if ( categoryNamePrefix ) then
return year .. '-е[[К:' .. categoryNamePrefix .. ' в ' .. year .. '-е годы]]';
else
return '' .. year;
end
end
end
 
function formatCentury( time, categoryNamePrefix )
local moduleRoman = require( "Module:RomanNumber" )
if ( time.year < 0 ) then
local century = math.floor( (math.abs( time.year) - 1) / 100 ) + 1;
if ( moduleRoman ) then
century = moduleRoman.toRomanNumber( century );
end
if ( categoryNamePrefix ) then
return '[[' .. century .. ' век до н. э.]][[К:' .. categoryNamePrefix .. ' в ' .. century .. ' веке до н. э.]]'
else
return '[[' .. century .. ' век до н. э.]]'
end
else
local century = math.floor( (time.year - 1) / 100 ) + 1;
if ( moduleRoman ) then
century = moduleRoman.toRomanNumber( century );
end
if ( categoryNamePrefix ) then
return '[[' .. century .. ' век]][[К:' .. categoryNamePrefix .. ' в ' .. century .. ' веке]]'
else
return '[[' .. century .. ' век]]'
end
end
end
 
function formatMillenium( time, categoryNamePrefix )
local moduleRoman = require( "Module:RomanNumber" )
if ( time.year < 0 ) then
local millenium = math.floor( (math.abs( time.year) - 1) / 1000 ) + 1;
if ( categoryNamePrefix ) then
return '[[' .. millenium .. ' тысячелетие до н. э.]][[К:' .. categoryNamePrefix .. ' в ' .. millenium .. ' тысячелетии до н. э.]]'
else
return '[[' .. millenium .. ' тысячелетие до н. э.]]'
end
else
local millenium = math.floor( (time.year - 1) / 1000 ) + 1;
if ( moduleRoman ) then
millenium = moduleRoman.toRomanNumber( millenium );
end
if ( categoryNamePrefix ) then
if ( millenium == 'II' ) then
return '[[' .. millenium .. ' тысячелетие]][[К:' .. categoryNamePrefix .. ' во ' .. millenium .. ' тысячелетии]]'
else
return '[[' .. millenium .. ' тысячелетие]][[К:' .. categoryNamePrefix .. ' в ' .. millenium .. ' тысячелетии]]'
end
else
return '[[' .. millenium .. ' тысячелетие]]'
end
end
end
 
function parseISO8601Date(str)
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local Y, M, D = mw.ustring.match( str, pattern )
return tonumber(Y), tonumber(M), tonumber(D)
end
function parseISO8601Time(str)
local pattern = "T(%d+):(%d+):(%d+)%Z"
local H, M, S = mw.ustring.match( str, pattern)
return tonumber(H), tonumber(M), tonumber(S)
end
function parseISO8601Offset(str)
if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
local pattern = "([-+])(%d%d):?(%d?%d?)$"
local sign, oh, om = mw.ustring.match( str, pattern)
sign, oh, om = sign or "+", oh or "00", om or "00"
return tonumber(sign .. oh), tonumber(sign .. om)
end
function parseISO8601(str)
if 'table'==type(str) then
if str.args and str.args[1] then
str = '' .. str.args[1]
else
return 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str )
end
end
local Y,M,D = parseISO8601Date(str)
local h,m,s = parseISO8601Time(str)
local oh,om = parseISO8601Offset(str)
return tonumber(os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s}))
end
 
local lowestBoundary = parseISO8601('-900-02-20T00:00:00Z')
local mainBoundary = parseISO8601('1582-10-05T00:00:00Z')
local lastBoundary = parseISO8601('1918-01-31T00:00:00Z');
 
boundaries = {
-- from (G) till next will be diff(G = J + diff), at current
{ lowestBoundary, -9 },
{ parseISO8601('-700-02-29T00:00:00Z'), -8 },
{ parseISO8601('-600-02-29T00:00:00Z'), -7 },
{ parseISO8601('-500-02-29T00:00:00Z'), -6 },
{ parseISO8601('-300-02-29T00:00:00Z'), -5 },
{ parseISO8601('-200-02-29T00:00:00Z'), -4 },
{ parseISO8601('-100-02-29T00:00:00Z'), -3 },
{ parseISO8601('0000-00-00T00:00:00Z'), -2 },
{ parseISO8601('0100-02-29T00:00:00Z'), -1 },
{ parseISO8601('0200-02-29T00:00:00Z'), 0 },
{ parseISO8601('0300-02-29T00:00:00Z'), 1 },
{ parseISO8601('0500-02-29T00:00:00Z'), 2 },
{ parseISO8601('0600-02-29T00:00:00Z'), 3 },
{ parseISO8601('0700-02-29T00:00:00Z'), 4 },
{ parseISO8601('0900-02-29T00:00:00Z'), 5 },
{ parseISO8601('1000-02-29T00:00:00Z'), 6 },
{ parseISO8601('1100-02-29T00:00:00Z'), 7 },
{ parseISO8601('1300-02-29T00:00:00Z'), 8 },
{ parseISO8601('1400-02-29T00:00:00Z'), 9 },
{ parseISO8601('1500-02-29T00:00:00Z'), 10 },
{ parseISO8601('1700-02-29T00:00:00Z'), 11 },
{ parseISO8601('1800-02-29T00:00:00Z'), 12 },
{ parseISO8601('1900-02-29T00:00:00Z'), 13 },
{ lastBoundary, '' },
};
 
-- Передаваемое время обязано быть по Юлианскому календарю (старому стилю)
function p.formatAsJulian( julTime, infocardClass, categoryNamePrefix )
if 'table' == type( julTime ) then
if julTime.args and julTime.args[1] then
julTime = tonumber( julTime.args[1] )
else
return 'unknown argument type: ' .. type( julTime ) .. ': ' .. table.tostring( julTime )
end
end
 
local t = os.date( "*t", julTime )
if ( julTime <= lowestBoundary ) then
return "''некорректная дата (недостижимая точность)''";
end
if ( julTime >= lastBoundary ) then
return "''некорректная дата (юлианский не используется после 1918-01-26)''";
end
 
for i=1,#boundaries,1 do
local b1 = boundaries[i][1];
local b2 = boundaries[i + 1][1];
if ( b1 <= julTime and julTime < b2 ) then
local b1s = os.date( "*t", b1 )
if ( b1s.year == t.year and b1s.month == t.month and b1s.day == t.day) then
if ( julTime < mainBoundary ) then
-- only julian
return moduleDates.formatWikiImpl( {year=t.year, month=2, day=29}, {year=t.year, month=2, day=29}, infocardClass, categoryNamePrefix );
else
--julian and grigorian
return moduleDates.formatWikiImpl( {year=t.year, month=2, day=29}, t, infocardClass, categoryNamePrefix )
end
else
local gregTime = os.date( "*t", julTime + boundaries[i][2] * 24 * 60 * 60 );
if ( julTime < mainBoundary ) then
-- only julian
return moduleDates.formatWikiImpl( t, t, infocardClass, categoryNamePrefix );
else
--julian and grigorian
return moduleDates.formatWikiImpl( t, gregTime, infocardClass, categoryNamePrefix )
end
end
end
end
 
if ( julTime >= lastBoundary ) then
return "''ошибка в модуле Модуль:Wikidata/date (не найден сдвиг конвертации календаря)''";
end
end