Намунаи фарохонии функсияҳои dateOfBirthВироиш

  • {{#invoke:Infocards|dateOfBirth|-382|−336}} → 382 то м.(-382)
  • {{#invoke:Infocards|dateOfBirth|11.1|}} → 11 январ
  • {{#invoke:Infocards|dateOfBirth|24.12.3|15.01.69}} → 24 декабр 3(0003-12-24)
  • {{#invoke:Infocards|dateOfBirth|23.09.-63|19.08.14}} → 23 сентябр 63 то м.(-063-09-23)
  • {{#invoke:Infocards|dateOfBirth|42|9.6.42}} → 42(0042)
  • {{#invoke:Infocards|dateOfBirth|870|13.8.900}} → 870(0870)
  • {{#invoke:Infocards|dateOfBirth||22.01.984}} →
  • {{#invoke:Infocards|dateOfBirth|16.06.1066|таърихи даргузашт номаълум}} → 16 июн 1066(1066-06-16)
  • {{#invoke:Infocards|dateOfBirth|8.2.1834 (27.1)|2.2.1907 (20.1)}} → 27 январ (8 феврал) 1834(1834-02-08)
  • {{#invoke:Infocards|dateOfBirth|29.06.1844 (17)|28.10.1883 (16)}} → 17 (29) июн 1844(1844-06-29)
  • {{#invoke:Infocards|dateOfBirth|19.7.1893 (7)|}} → 7 (19) июл 1893(1893-07-19)
  • {{#invoke:Infocards|dateOfBirth|3.10.1895 (21.9)|28.12.1925}} → 21 сентябр (3 октябр) 1895(1895-10-03)
  • {{#invoke:Infocards|dateOfBirth|4.10.1916|8.11.2009}} → 4 октябр 1916(1916-10-04)
  • {{#invoke:Infocards|dateOfBirth|09.06.1942|}} → 9 июн 1942(1942-06-09) (81 сол)
  • {{#invoke:Infocards|dateOfBirth|1955|}} → 1955(1955)
  • {{#invoke:Infocards|dateOfBirth|29.02.1984|}} → 29 феврал 1984(1984-02-29) (39 сол)
  • {{#invoke:Infocards|dateOfBirth||}} →
  • {{#invoke:Infocards|dateOfBirth|4.1.1885 (23.12.1884)|17.5.1951}} → 23 декабр 1884 (4 январ 1885)(1885-01-04)
  • {{#invoke:Infocards|dateOfBirth|{{СанаиТаваллуд|24|12|3}}|{{СанаиМарг|15|01|69}}}} → 24 декабр 3
  • {{#invoke:Infocards|dateOfBirth|ок. [[5]] года|24.01.41}} → ок. 5 года
  • {{#invoke:Infocards|dateOfBirth|ок. [[5]] года|{{СанаиМарг|24|01|41}}}} → ок. 5 года
  • {{#invoke:Infocards|dateOfBirth|[[868]]/[[872]]|[[15 сентябр]]и/[[15 ноябр]]и [[890]]}} → 868/872
  • {{#invoke:Infocards|dateOfBirth|{{СанаиТаваллуд|8|2|1834|27|1}}|{{СанаиМарг|2|2|1907|20|1}} (72 года)}} → 27 январ (8 феврал) 1834

Примеры вызова функции dateOfDeathВироиш

  • {{#invoke:Infocards|dateOfDeath|-382|−336}} → 336 то м.(-336)
  • {{#invoke:Infocards|dateOfDeath|24.12.3|15.01.69}} → 15 январ 69(0069-01-15) (65 сол)
  • {{#invoke:Infocards|dateOfDeath|23.09.-63|19.08.14}} → 19 август 14(0014-08-19) (76 сол)
  • {{#invoke:Infocards|dateOfDeath|42|9.6.42}} → 9 июн 42(0042-06-09)
  • {{#invoke:Infocards|dateOfDeath|870|13.8.900}} → 13 август 900(0900-08-13)
  • {{#invoke:Infocards|dateOfDeath||22.01.984}} → 22 январ 984(0984-01-22)
  • {{#invoke:Infocards|dateOfDeath|16.06.1066|таърихи даргузашт номаълум}} → таърихи даргузашт номаълум
  • {{#invoke:Infocards|dateOfDeath|8.2.1834 (27.1)|2.2.1907 (20.1)}} → 20 январ (2 феврал) 1907(1907-02-02) (72 сол)
  • {{#invoke:Infocards|dateOfDeath|29.06.1844 (17)|28.10.1883 (16)}} → 16 (28) октябр 1883(1883-10-28) (39 сол)
  • {{#invoke:Infocards|dateOfDeath|19.7.1893 (7)|}} → 14 апрел 1930(1930-04-14) (36 сол)
  • {{#invoke:Infocards|dateOfDeath|3.10.1895 (21.9)|28.12.1925}} → 28 декабр 1925(1925-12-28) (30 сол)
  • {{#invoke:Infocards|dateOfDeath|4.10.1916|8.11.2009}} → 8 ноябр 2009(2009-11-08) (93 сол)
  • {{#invoke:Infocards|dateOfDeath|09.06.1942|}} →
  • {{#invoke:Infocards|dateOfDeath|1955|}} →
  • {{#invoke:Infocards|dateOfDeath|29.02.1984|}} →
  • {{#invoke:Infocards|dateOfDeath||}} →
  • {{#invoke:Infocards|dateOfDeath|{{СанаиТаваллуд|24|12|3}}|{{СанаиМарг|15|01|69}}}} → 15 январи 69
  • {{#invoke:Infocards|dateOfDeath|[[5]] ок. соли|24.01.41}} → 24 январ 41(0041-01-24)
  • {{#invoke:Infocards|dateOfDeath|ок. [[5]] года|{{СанаиМарг|24|01|41}}}} → 24 январи 41
  • {{#invoke:Infocards|dateOfDeath|[[868]]/[[872]]|[[15 сентябр]]и/[[15 ноябр]]и [[890]]}} → 15 сентябри/15 ноябри 890
  • {{#invoke:Infocards|dateOfDeath|{{СанаиТаваллуд|8|2|1834|27|1}}|{{СанаиМарг|2|2|1907|20|1}} (72 года)}} → 20 январ (2 феврал)-и 1907 (72 года)

Примеры вызова функции isDateВироиш

  • {{#invoke:Infocards|isDate||TRUE|FALSE}} → FALSE
  • {{#invoke:Infocards|isDate|-382|TRUE|FALSE}} → TRUE
  • {{#invoke:Infocards|isDate|−336|TRUE|FALSE}} → TRUE
  • {{#invoke:Infocards|isDate|24.12.3|TRUE|FALSE}} → TRUE
  • {{#invoke:Infocards|isDate|19.7.1893 (7)|TRUE|FALSE}} → TRUE
  • {{#invoke:Infocards|isDate|19.7.67.18/93 (7)|TRUE|FALSE}} → FALSE
  • {{#invoke:Infocards|isDate|13 декабря 2005|TRUE|FALSE}} → FALSE
  • {{#invoke:Infocards|isDate|дата смерти неизвестна|TRUE|FALSE}} → FALSE
  • {{#invoke:Infocards|isDate|{{СанаиТаваллуд|24|12|3}}|TRUE|FALSE}} → FALSE

local infocards = {};
local calculateAge = true;

--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters.  This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function infocards._getParameters( frame_args, arg_list )
    local new_args = {};
    local index = 1;
    local value;
 
    for i,arg in ipairs( arg_list ) do
        value = frame_args[arg]
        if value == nil then
            value = frame_args[index];
            index = index + 1;
        end
        new_args[arg] = value;
    end
 
    return new_args;
end        

function infocards.isBlank( someString )
    return someString == nil or mw.ustring.match(someString, '^%s*$') ~= nil;
end

function infocards.isDate ( frame )
    local new_args = infocards._getParameters( frame.args, {'s', 't', 'f'} );
    local s = new_args['s'] or '';
    local t = new_args['t'] or '';
    local f = new_args['f'] or '';

    local result = infocards.isDateImpl ( s )
    if (result) then
        return t
    else
        return f
    end
end

function infocards.isDateImpl ( s )
    local converted = infocards.convertToDate ( s );
    return converted ~= nil
end

function infocards.dateOfBirth( frame )
    local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'suppressAge', 'nocat'} );
    local dateOfBirth = new_args['dateOfBirth'] or '';
    local dateOfDeath = new_args['dateOfDeath'] or '';
    local suppressAge = new_args['suppressAge'] or '';
    local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText;

    return infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat );
end

function infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat )

    local appendToCategory = infocards.isBlank( nocat );

    if ( infocards.isBlank( dateOfBirth ) ) then
        if ( appendToCategory ) then
             return '[[Гурӯҳ:Википедия:Шахсиятҳо бе нишон додани таърихи таваллуд]]'
        else
            return ''
        end
    end

    if ( mw.ustring.match( dateOfBirth, '^%s*номаълум.%s*$' ) ~= nil
            or mw.ustring.match( dateOfBirth, '^%s*%?%s*$' ) ~= nil ) then
        if ( appendToCategory ) then
            return "''номаълум''[[Гурӯҳ:Ашхосе, ки таърихи таваллудашон оварда нашудааст]]"
        else
            return "''номаълум''"
        end
    end

    local appendAge = not (suppressAge ~= '' or not calculateAge) and infocards.isBlank( dateOfDeath );

    local parsedDate = infocards.convertToDate ( dateOfBirth )
    if ( parsedDate == nil ) then
		--[[ Temporary hack in order to enable export dates to wikidata ]]
		local bDateStart = '<span class="no-wikidata" data-wikidata-property-id="P569">'
		local bDateEnd = '</span>'

        if ( appendToCategory ) then
            return bDateStart .. dateOfBirth .. bDateEnd .. '[[Гурӯҳ:Википедиа:Мақолаҳо бо викификатсияи дастии таърих дар қуттӣ]]'
        else
            return bDateStart .. dateOfBirth .. bDateEnd
        end
    end

    local result = infocards.formatDateImpl ( parsedDate, 'bday', appendToCategory and 'Зодагони' or nil )

    if ( appendAge ) then
        -- TODO: месяцы и дни для (нескольких) новорождённых (см. новейшие [[Гурӯҳ:Зодагони соли СССС]])
        local age = infocards.age ( parsedDate,  os.date("*t") )
        if ( age and age > 0 and age < 125) then
            result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'tg' ):plural( age, 'сола', 'сол', 'сола') .. ')</span>'
        end
        
		if ( appendToCategory ) then
			if ( age and age > 115 ) then
				result = result .. '[[Гурӯҳ:Википедия:Мақолаҳо дар бораи ашхоси бо синну соли калони ҷорӣ]]'
			elseif ( age or ( parsedDate and parsedDate.year and os.date('*t').year - parsedDate.year <= 115 ) ) then  -- утверждение во вложенных скобках вступает при неточной дате
				result = result .. '[[Гурӯҳ:Википедия:Зиндагиномаи муосирон]]'
			end
		end
    end

    return result
end

function infocards.dateOfDeath( frame )
    local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'nocat'} );
    local dateOfBirth = new_args['dateOfBirth'] or '';
    local dateOfDeath = new_args['dateOfDeath'] or '';
    local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText;

    return infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat );
end

function infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat )
    if ( infocards.isBlank( dateOfDeath ) ) then
        return ''
    end

    local appendToCategory = infocards.isBlank( nocat );

    if ( mw.ustring.match( dateOfDeath, '^%s*номаъл.%s*$' ) ~= nil
            or mw.ustring.match( dateOfDeath, '^%s*%?%s*$' ) ~= nil ) then
        if ( appendToCategory ) then
            return "''номаълум''[[Гурӯҳ:Ашхосе, ки таърихи даргузашташон оварда нашудааст]]"
        else
            return "''номаълум''"
        end
    end

    local parsedDateOfBirth = infocards.convertToDate ( dateOfBirth )
    local parsedDateOfDeath = infocards.convertToDate ( dateOfDeath )

    if ( parsedDateOfDeath == nil ) then
		--[[ Temporary hack in order to enable export dates to wikidata ]]
		local dDateStart = '<span class="no-wikidata" data-wikidata-property-id="P570">'
		local dDateEnd = '</span>'

        if ( appendToCategory ) then
            return dDateStart .. dateOfDeath .. dDateEnd .. '[[Гурӯҳ:Википедиа:Мақолаҳо бо викификатсияи дастии таърих дар қуттӣ]]'
        else
            return dDateStart .. dateOfDeath .. dDateEnd
        end
    end

    local result = infocards.formatDateImpl ( parsedDateOfDeath, 'dday', appendToCategory and 'Даргузаштагони' or nil )

	if ( calculateAge ) then
		local age = infocards.age ( parsedDateOfBirth, parsedDateOfDeath )
		if ( age and age > 0 ) then
			result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'tg' ):plural( age, 'сол', 'сол', 'сола') .. ')</span>'
		end
		
		-- returns category to recently deceased persons
		local unixAvailable, unixDateOfDeath = pcall(function()
			local r = os.time(parsedDateOfDeath)
			if ( r ~= os.time() ) then
				return r
			end
			error()
		end)
		if ( unixAvailable and os.time() - unixDateOfDeath < 31536000 and appendToCategory ) then
			result = result .. '[[Гурӯҳ:Википедия:Ашхосе, ки то як соли пеш фавт кардаанд]]'
		end
	end

    return result
end

function infocards.age( parsedBirthDate, parsedFinishDate ) 
    if ( parsedBirthDate == nil or parsedFinishDate == nil ) then
        return nil
    end

    local bd = parsedBirthDate["day"]
    local bm = parsedBirthDate["month"]
    local by = parsedBirthDate["year"]

    local dd = parsedFinishDate["day"];
    local dm = parsedFinishDate["month"];
    local dy = parsedFinishDate["year"];

    if ( bd and bm and by and dd and dm and dy ) then
        if ( dm > bm or ( dm == bm and dd >= bd ) ) then
            return dy - by
        else
            return dy - by - 1
        end
    else
        return nil
    end
end

local genitivusMonthes = {'январ', 'феврал', 'март', 'апрел', 'май', 'июн',
    'июл', 'август', 'сентябр', 'октябр', 'ноябр', 'декабр'}

function infocards.formatDateImpl( parsedDate, infocardClass, categoryNamePrefix )
    local nd = parsedDate["day"];
    local nm = parsedDate["month"];
    local ny = parsedDate["year"];
    local od = parsedDate["osday"];
    local om = parsedDate["osmonth"];
    local oy = parsedDate["osyear"];
    
    local template =
        (nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "") ..
        (od ~= nil and "4" or "") .. (om ~= nil and "5" or "") .. (oy ~= nil and "6" or "")

    local datePart = '<span class="nowrap">'
    if (infocardClass == "bday") then --[[ Temporary hack in order to enable export dates to wikidata ]]
    	datePart = '<span class="no-wikidata" data-wikidata-property-id="P569">'
    elseif (infocardClass == "dday") then
    	datePart = '<span class="no-wikidata" data-wikidata-property-id="P570">'
    end	
    if (template == "12") then
        datePart = datePart .. string.format( "[[%d %s]]", nd, genitivusMonthes[nm] )
    elseif (template == "3") then
        datePart = datePart .. infocards.nominativeYear( ny )
    elseif (template == "123") then
        datePart = datePart .. string.format( "[[%d %s]] %s",
                                        nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
    elseif (template == "124") then
        datePart = datePart .. string.format( "[[%d %s|%d (%d) %s]]",
                                        nd, genitivusMonthes[nm], od, nd, genitivusMonthes[nm] )
    elseif (template == "1234") then
        datePart = datePart .. string.format( "[[%d %s|%d (%d) %s]] %s",
                                        nd, genitivusMonthes[nm], od, nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
    elseif (template == "1245") then
        datePart = datePart .. string.format( "%d %s ([[%d %s]])",
                                        od, genitivusMonthes[om], nd, genitivusMonthes[nm] )
    elseif (template == "12345") then
        datePart = datePart .. string.format( "%d %s ([[%d %s]]) %s",
                                        od, genitivusMonthes[om], nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
    elseif (template == "123456") then
        datePart = datePart .. string.format( '%d %s %d</span> <span class="nowrap">([[%d %s]] %s)',
                                        od, genitivusMonthes[om], oy, nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
    else
        datePart = datePart .. 'формати нодуруст'
    end
    datePart = datePart .. '</span>'

    local infocardTemplate =
        (nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "")

	if (infocardTemplate == "123") then
		datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d-%02d</span>)</span>', infocardClass , ny , nm , nd )
	elseif (infocardTemplate == "23") then
		datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d</span>)</span>', infocardClass , ny , nm )
	elseif (infocardTemplate == "3") then
		datePart = datePart .. string.format('<span style="display:none;">(<span class="%s">%04d</span>)</span>', infocardClass , ny )
	end

    if ( categoryNamePrefix ~= nil ) then
        if ( nd ~= nil and nm ~= nil) then
            datePart = datePart .. '[[Гурӯҳ:' .. categoryNamePrefix .. ' ' .. nd .. ' ' .. genitivusMonthes[nm] .. ']]'
        end
        if ( ny ~= nil) then
            datePart = datePart .. '[[Гурӯҳ:' .. categoryNamePrefix .. '  ' .. infocards.inYear( ny ) .. ']]'
        end
    end

    return datePart
end

function infocards.nominativeYear( year )
    if ( year >= 0 ) then
        return '[[соли ' .. year .. '|' .. year .. ']]'
    else
        return '[[соли ' .. ( 0 - year ) .. ' то м.|' .. ( 0 - year ) .. ' то м.]]'
    end
end

function infocards.inYear( year )
    if ( year >= 0 ) then
        return 'соли ' .. year .. ''
    else
        return 'соли ' .. ( 0 - year) .. ' то м.'
    end
end

function infocards.convertToDate( possibleDateString )

    possibleDateString = mw.ustring.gsub( possibleDateString, '−', '-')

    local simpleDate = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*$', 0)
    if ( simpleDate ) then
        return infocards.convertToDateNewStylePart( simpleDate );
    end

    local complexDate1, complexDate2 = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*%(([%-%d%.]+)%)%s*$', 0)
    if ( complexDate1 and complexDate2) then
        local table1 = infocards.convertToDateNewStylePart( complexDate1 );
        local table2 = infocards.convertToDateOldStylePart( complexDate2 );
        if ( table1 and table2 ) then
            return {
                    year = table1["year"], month = table1["month"], day = table1["day"], 
                    osyear = table2["year"], osmonth = table2["month"], osday = table2["day"]
                }
        else
            return nil
        end
    end

    return nil
end

function infocards.convertToDateNewStylePart( possibleDateString )

    local ny = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0)
    if (ny ~= nil) then
        return {year = tonumber(ny)}
    end

    return infocards.convertToDateCommonPart( possibleDateString )
end

function infocards.convertToDateOldStylePart( possibleDateString )

    local nd = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0)
    if (nd ~= nil) then
        return {day = tonumber(nd)}
    end

    return infocards.convertToDateCommonPart( possibleDateString )
end


function infocards.convertToDateCommonPart( possibleDateString )

    local nd, nm
        = mw.ustring.match(possibleDateString, '^(%d?%d)%.(%d?%d)$', 0)
    if (nd ~= nil and nm ~= nil) then
        return {day = tonumber(nd), month = tonumber(nm)}
    end

    local nd, nm, ny
        = mw.ustring.match(possibleDateString, '^(%d?%d)%.(%d?%d)%.(%-?%d+)$', 0)
    if (nd ~= nil and nm ~= nil and ny ~= nil) then
    	local ndn = tonumber(nd)
    	local nmn = tonumber(nm)
    	local nyn = tonumber(ny)
    	if (ndn > 0 and ndn < 33 and nmn > 0 and nmn < 13) then
        	return {day = ndn, month = nmn, year = nyn}
        end
    end

    return nil
end

return infocards