<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>http://new.ru-skazki.ru/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3A%D0%9F%D0%B5%D1%81%D0%BE%D1%87%D0%BD%D0%B8%D1%86%D0%B0%2FCarn%2FCalendar</id>
	<title>Модуль:Песочница/Carn/Calendar - История изменений</title>
	<link rel="self" type="application/atom+xml" href="http://new.ru-skazki.ru/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3A%D0%9F%D0%B5%D1%81%D0%BE%D1%87%D0%BD%D0%B8%D1%86%D0%B0%2FCarn%2FCalendar"/>
	<link rel="alternate" type="text/html" href="http://new.ru-skazki.ru/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:%D0%9F%D0%B5%D1%81%D0%BE%D1%87%D0%BD%D0%B8%D1%86%D0%B0/Carn/Calendar&amp;action=history"/>
	<updated>2026-04-23T16:30:53Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>http://new.ru-skazki.ru/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:%D0%9F%D0%B5%D1%81%D0%BE%D1%87%D0%BD%D0%B8%D1%86%D0%B0/Carn/Calendar&amp;diff=780&amp;oldid=prev</id>
		<title>Andras: Новая страница: «local p = {} local getArgs = require(&#039;Module:Arguments&#039;).getArgs local yesno = require(&#039;Module:Yesno&#039;) local snippet = require(&#039;Module:Песочница/Carn/Text&#039;) local function is(str) 	if (not str) or (str == &quot;&quot;) then return false 	else return yesno(str,false) end end  --[==[ Таблицы с данными для работы модуля ]==]  local pattern = { -- для распознавания дат, переданных одним строчн...»</title>
		<link rel="alternate" type="text/html" href="http://new.ru-skazki.ru/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:%D0%9F%D0%B5%D1%81%D0%BE%D1%87%D0%BD%D0%B8%D1%86%D0%B0/Carn/Calendar&amp;diff=780&amp;oldid=prev"/>
		<updated>2023-05-11T14:47:10Z</updated>

		<summary type="html">&lt;p&gt;Новая страница: «local p = {} local getArgs = require(&amp;#039;Module:Arguments&amp;#039;).getArgs local yesno = require(&amp;#039;Module:Yesno&amp;#039;) local snippet = require(&amp;#039;Module:Песочница/Carn/Text&amp;#039;) local function is(str) 	if (not str) or (str == &amp;quot;&amp;quot;) then return false 	else return yesno(str,false) end end  --[==[ Таблицы с данными для работы модуля ]==]  local pattern = { -- для распознавания дат, переданных одним строчн...»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
local getArgs = require(&amp;#039;Module:Arguments&amp;#039;).getArgs&lt;br /&gt;
local yesno = require(&amp;#039;Module:Yesno&amp;#039;)&lt;br /&gt;
local snippet = require(&amp;#039;Module:Песочница/Carn/Text&amp;#039;)&lt;br /&gt;
local function is(str)&lt;br /&gt;
	if (not str) or (str == &amp;quot;&amp;quot;) then return false&lt;br /&gt;
	else return yesno(str,false) end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[==[ Таблицы с данными для работы модуля ]==]&lt;br /&gt;
&lt;br /&gt;
local pattern = { -- для распознавания дат, переданных одним строчным параметром&lt;br /&gt;
	{&amp;quot;(-?%d+%d*)-(%d+)-(%d+)&amp;quot;,  	[&amp;quot;order&amp;quot;] = {3,2,1} },  -- y-m-d&lt;br /&gt;
	{&amp;quot;(%d+)%.(%d+)%.(-?%d+%d*)&amp;quot;,	[&amp;quot;order&amp;quot;] = {1,2,3} }, 	-- d.m.y&lt;br /&gt;
	{&amp;quot;(%d+)%s(%d+)%s(-?%d+%d*)&amp;quot;,	[&amp;quot;order&amp;quot;] = {1,2,3} }, 	-- d m y&lt;br /&gt;
	{&amp;quot;(%d+)%s(%a+)%s(-?%d+%d*)&amp;quot;, 	[&amp;quot;order&amp;quot;] = {1,2,3} }, 	-- d mmm y&lt;br /&gt;
	} &lt;br /&gt;
&lt;br /&gt;
local time_units = {&amp;quot;year&amp;quot;,&amp;quot;month&amp;quot;,&amp;quot;day&amp;quot;}&lt;br /&gt;
--[[ local time_units = {&amp;quot;second&amp;quot;, &amp;quot;minute&amp;quot;, &amp;quot;hour&amp;quot;, &lt;br /&gt;
	&amp;quot;day_of_month&amp;quot;, &amp;quot;day_of_week&amp;quot;, &amp;quot;day_of_year&amp;quot;, &lt;br /&gt;
	&amp;quot;week&amp;quot;, &amp;quot;month&amp;quot;, &amp;quot;year&amp;quot;, &amp;quot;year_of_century&amp;quot;, &amp;quot;century&amp;quot;} ]]--&lt;br /&gt;
-- напоминание чтобы сделать расчёт длительностей периодов&lt;br /&gt;
&lt;br /&gt;
local category_msg = &amp;quot;&amp;quot;&lt;br /&gt;
local category = {&lt;br /&gt;
	[&amp;quot;incomplete_parameters&amp;quot;]=&lt;br /&gt;
	&amp;quot;&amp;lt;!--[[Категория:Модуль:Calendar:Страницы с неполными или некорректными параметрами]]--&amp;gt;&amp;quot;,&lt;br /&gt;
	[&amp;quot;without_verification&amp;quot;]=&lt;br /&gt;
	&amp;quot;&amp;lt;!--[[Категория:Модуль:Calendar:Страницы без проверки параметров]]--&amp;gt;&amp;quot;,&lt;br /&gt;
	[&amp;quot;erroneous_parameters&amp;quot;]=&lt;br /&gt;
	&amp;quot;&amp;lt;!--[[Категория:Модуль:Calendar:Страницы с ошибочными параметрами]]--&amp;gt;&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- несколько параметров передаются вместе с кодом ошибки в таблице, один может быть передан простым значением&lt;br /&gt;
local errors = {&lt;br /&gt;
	[&amp;quot;start&amp;quot;]=&amp;quot;&amp;lt;span class=error&amp;gt;Ошибка: &amp;quot;,&lt;br /&gt;
	[&amp;quot;ending&amp;quot;]=&amp;quot;.&amp;lt;/span&amp;gt;&amp;quot;,&lt;br /&gt;
	[&amp;quot;no_pattern_match&amp;quot;]=&amp;quot;строка «%s» не совпадает с заданными паттернами&amp;quot;,&lt;br /&gt;
	[&amp;quot;no_valid_date&amp;quot;]=&amp;quot;дата «%s·%s·%s» не является корректной&amp;quot;,&lt;br /&gt;
	[&amp;quot;wrong_jd&amp;quot;]=&amp;quot;юлианская дата %s вне диапазона&amp;quot;,&lt;br /&gt;
	[&amp;quot;too_many_arguments&amp;quot;]=&amp;quot;ожидается менее %i аргументов&amp;quot;,&lt;br /&gt;
	[&amp;quot;too_little_arguments&amp;quot;]=&amp;quot;ожидается более %i аргументов&amp;quot;,&lt;br /&gt;
	[&amp;quot;wrong_calculation&amp;quot;]=&amp;quot;даты %s и %s не прошли проверку, %s дней разница&amp;quot;,&lt;br /&gt;
	[&amp;quot;unknown_calendar&amp;quot;]=&amp;quot;параметр календаря %s неизвестен&amp;quot;,&lt;br /&gt;
	[&amp;quot;unknown_error&amp;quot;]=&amp;quot;неизвестная ошибка&amp;quot;,&lt;br /&gt;
	[&amp;quot;tech_error&amp;quot;]=&amp;quot;ошибка в функции %s&amp;quot;,&lt;br /&gt;
--	[&amp;quot;&amp;quot;]=&amp;quot;&amp;quot;,&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
-- для повышения гибкости вывода можно указать отдельные параметры для первой и второй даты&lt;br /&gt;
-- для повышения удобства пользователя заданные одним параметром аргументы дублируются&lt;br /&gt;
local calendars = {{&amp;quot;г&amp;quot;, &amp;quot;g&amp;quot;}, {&amp;quot;ю&amp;quot;, &amp;quot;j&amp;quot;}}&lt;br /&gt;
local unik_args = {	&amp;quot;order&amp;quot;,&amp;quot;lang&amp;quot;, &amp;quot;cal&amp;quot;, &amp;quot;bc&amp;quot;, &amp;quot;sq_brts&amp;quot; }&lt;br /&gt;
local unik_args_bool = {false,false,false,true,true,true}&lt;br /&gt;
-- before christ, calendar, brackets inside, square brackets&lt;br /&gt;
local dual_args = { &amp;quot;wdm&amp;quot;, &amp;quot;wy&amp;quot;, &amp;quot;ny&amp;quot;, &amp;quot;ym&amp;quot;}&lt;br /&gt;
local dual_args_bool = {true,true,true,false}&lt;br /&gt;
-- wikify day and month, wikify year, no year, year mark&lt;br /&gt;
&lt;br /&gt;
local status = {category=&amp;quot;&amp;quot;,error={msg=&amp;quot;&amp;quot;,params=&amp;quot;&amp;quot;}}&lt;br /&gt;
local bool2num={[1]=1, [0]=0, [&amp;quot;1&amp;quot;]=1, [&amp;quot;0&amp;quot;]=0, [true]=1, [false]=0, &lt;br /&gt;
	[&amp;quot;__index&amp;quot;]=function(self,v) &lt;br /&gt;
		return tostring(v)&lt;br /&gt;
	end }&lt;br /&gt;
setmetatable(bool2num,bool2num)&lt;br /&gt;
&lt;br /&gt;
-- local options = {&amp;quot;cal&amp;quot;,&amp;quot;bc&amp;quot;,&amp;quot;wiki_date&amp;quot;,&amp;quot;wiki_year&amp;quot;,&amp;quot;sq_brts&amp;quot;,&amp;quot;no_year&amp;quot;,&amp;quot;brackets_inside&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
-- в случае обновления таблицы названий месяцев необходимо также обновлять список кодов языков&lt;br /&gt;
local bc_mark = &amp;quot;до н. э.&amp;quot;&lt;br /&gt;
local lang = {&amp;quot;ru&amp;quot;, &amp;quot;en&amp;quot;, &amp;quot;de&amp;quot;, &amp;quot;fr&amp;quot;}&lt;br /&gt;
local month_lang = {&lt;br /&gt;
	[&amp;quot;ru&amp;quot;] = {&amp;quot;января&amp;quot;,&amp;quot;февраля&amp;quot;,&amp;quot;марта&amp;quot;,&amp;quot;апреля&amp;quot;,&amp;quot;мая&amp;quot;,&amp;quot;июня&amp;quot;,&lt;br /&gt;
		&amp;quot;июля&amp;quot;,&amp;quot;августа&amp;quot;,&amp;quot;сентября&amp;quot;,&amp;quot;октября&amp;quot;,&amp;quot;ноября&amp;quot;,&amp;quot;декабря&amp;quot;},&lt;br /&gt;
	[&amp;quot;en&amp;quot;] = {&amp;quot;january&amp;quot;, &amp;quot;february&amp;quot;, &amp;quot;march&amp;quot;, &amp;quot;april&amp;quot;, &amp;quot;may&amp;quot;, &amp;quot;june&amp;quot;, &lt;br /&gt;
		&amp;quot;july&amp;quot;, &amp;quot;august&amp;quot;, &amp;quot;september&amp;quot;, &amp;quot;october&amp;quot;, &amp;quot;november&amp;quot;, &amp;quot;december&amp;quot;},&lt;br /&gt;
	[&amp;quot;de&amp;quot;] = {&amp;quot;januar&amp;quot;, &amp;quot;februar&amp;quot;, &amp;quot;märz&amp;quot;, &amp;quot;april&amp;quot;, &amp;quot;mai&amp;quot;, &amp;quot;juni&amp;quot;, &lt;br /&gt;
		&amp;quot;juli&amp;quot;, &amp;quot;august&amp;quot;, &amp;quot;september&amp;quot;, &amp;quot;oktober&amp;quot;, &amp;quot;november&amp;quot;, &amp;quot;dezember&amp;quot;},&lt;br /&gt;
	[&amp;quot;fr&amp;quot;] = {&amp;quot;janvier&amp;quot;, &amp;quot;février&amp;quot;, &amp;quot;mars&amp;quot;, &amp;quot;avril&amp;quot;, &amp;quot;mai&amp;quot;, &amp;quot;juin&amp;quot;, &lt;br /&gt;
		&amp;quot;juillet&amp;quot;, &amp;quot;août&amp;quot;, &amp;quot;septembre&amp;quot;, &amp;quot;octobre&amp;quot;, &amp;quot;novembre&amp;quot;, &amp;quot;décembre&amp;quot;}&lt;br /&gt;
	}&lt;br /&gt;
-- заполняется автоматически&lt;br /&gt;
local reverse_month_lang = {}&lt;br /&gt;
&lt;br /&gt;
-- вспомогательная функция для обращения таблиц (смена ключей со значениями)&lt;br /&gt;
local reverse_table = function (strait_table) &lt;br /&gt;
	local reversed_table = {}&lt;br /&gt;
	for k,v in pairs(strait_table) do&lt;br /&gt;
		reversed_table[v] = k&lt;br /&gt;
	end&lt;br /&gt;
	return reversed_table&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- запуск цикла по заполнению обратных таблиц, необходимых для распознавания дат&lt;br /&gt;
local filling_months = function (lang, month_lang)&lt;br /&gt;
	for i=1, #lang do&lt;br /&gt;
		reverse_month_lang[lang[i]] = reverse_table(month_lang[lang[i]])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[==[ Функции универсального назначения ]==]&lt;br /&gt;
-- вспомогательная функция для проверки вхождения числа в диапазон&lt;br /&gt;
local function number_in_range(value, bottom, top)&lt;br /&gt;
	if type(value) ~= &amp;quot;number&amp;quot; or type(top) ~= &amp;quot;number&amp;quot; or type(bottom) ~= &amp;quot;number&amp;quot; &lt;br /&gt;
		or top &amp;lt; bottom or value &amp;lt; bottom or value &amp;gt; top then return false&lt;br /&gt;
    else return true end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- mw.clone копирует с метатаблицами&lt;br /&gt;
-- для определения наибольшего индекса в таблице есть table.maxn&lt;br /&gt;
local function copy_it(original)&lt;br /&gt;
	local c = {}&lt;br /&gt;
	if type(original) == &amp;quot;table&amp;quot; then&lt;br /&gt;
		for key, value in pairs(original) do&lt;br /&gt;
			if value == &amp;quot;&amp;quot; or value == &amp;quot; &amp;quot; then&lt;br /&gt;
				value = nil&lt;br /&gt;
			end&lt;br /&gt;
			c[key] = value&lt;br /&gt;
		end&lt;br /&gt;
	else return original, 1&lt;br /&gt;
	end&lt;br /&gt;
	for i = 7, 1, -1 do&lt;br /&gt;
		if c[i] then &lt;br /&gt;
			return c, i&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return c, 0&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
-- функция, определяющая, содержит ли таблица необходимое число аргументов&lt;br /&gt;
local function is_complete(table_in,start,finish)&lt;br /&gt;
	if type(table_in) ~= &amp;quot;table&amp;quot; or type(start) ~= &amp;quot;number&amp;quot; or type(finish) ~= &amp;quot;number&amp;quot; or start &amp;gt; finish then &lt;br /&gt;
		return nil&lt;br /&gt;
	else &lt;br /&gt;
		for i=start,finish do&lt;br /&gt;
			if not table_in[i] then &lt;br /&gt;
				return false &lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- функция для проверки, содержит ли массив запрашиваемое значение&lt;br /&gt;
local is_in_list = function ( var, list )&lt;br /&gt;
	for i=1, #list do&lt;br /&gt;
		if var == list[i] then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
    return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--XXX--&lt;br /&gt;
--[==[ Календарные функции ]==]&lt;br /&gt;
-- функция для вычисления последнего дня месяца для юлианского и григорианского календарей&lt;br /&gt;
local function month_end_day (month,year,is_julian)&lt;br /&gt;
	local month_end_day = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -- если не задан год, дата 29 февраля считается допустимой&lt;br /&gt;
	if not month or type(month) ~= &amp;quot;number&amp;quot; or month &amp;lt; 1 or month &amp;gt; 12 then return nil&lt;br /&gt;
	elseif month ~= 2 or not year then return month_end_day[month] &lt;br /&gt;
	elseif month == 2 and (year % 4) == 0 and not ((not is_julian) and (year % 100 == 0 and year % 400 ~= 0)) then return 29&lt;br /&gt;
	elseif month == 2 then return 28&lt;br /&gt;
	else return nil -- в случае не целого значения входящих параметров или при иных непредусмотренных событиях&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- функция, проверяющая, корректная ли дата содержится в таблице&lt;br /&gt;
local function is_date ( date, is_julian )&lt;br /&gt;
	if not date or type(date) ~= &amp;quot;table&amp;quot; then return false&lt;br /&gt;
	elseif	not number_in_range(date.month,1,12) or&lt;br /&gt;
			not number_in_range(date.day,1,month_end_day(date.month,date.year,is_julian)) or&lt;br /&gt;
			not number_in_range(date.year,-9999,9999) then&lt;br /&gt;
				return false&lt;br /&gt;
	elseif date.year ~= 0 then return true&lt;br /&gt;
	end&lt;br /&gt;
end		&lt;br /&gt;
&lt;br /&gt;
-- функция для проверки, содержит ли таблица частичные сведения о дате&lt;br /&gt;
local function is_date_part ( date )&lt;br /&gt;
	if not date then return false&lt;br /&gt;
	elseif not (type(date) == &amp;quot;table&amp;quot;) then return false&lt;br /&gt;
	elseif (number_in_range(date.year,-9999,9999)&lt;br /&gt;
	or number_in_range(date.month,1,12)&lt;br /&gt;
	or number_in_range(date.day,1,31)) then return true&lt;br /&gt;
	else return false&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- для дат, порядок которых неизвестен, пробует сначала прямой (dmy), затем обратный (ymd) порядок&lt;br /&gt;
local function guess_date( triplet, is_julian ) -- только для дат после 31 года, пока не используется&lt;br /&gt;
	local date = {[&amp;quot;day&amp;quot;]=triplet[1],[&amp;quot;month&amp;quot;]=triplet[2],[&amp;quot;year&amp;quot;]=triplet[3]}&lt;br /&gt;
	if is_date(date,is_julian) then return date end&lt;br /&gt;
	local date = {[&amp;quot;day&amp;quot;]=triplet[3],[&amp;quot;month&amp;quot;]=triplet[2],[&amp;quot;year&amp;quot;]=triplet[1]}&lt;br /&gt;
	if is_date(date,is_julian) then return date end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- конвертация григорианской даты в jd [[Julian day]]&lt;br /&gt;
function gri2jd( datein )&lt;br /&gt;
	if not is_date(datein) then &lt;br /&gt;
--		if type(status.error) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
--			status.error = {}&lt;br /&gt;
--		end&lt;br /&gt;
--		status.error.msg = &amp;quot;no_valid_date&amp;quot;&lt;br /&gt;
--		status.error.params = datein&lt;br /&gt;
		return --status &lt;br /&gt;
	end&lt;br /&gt;
    local year = datein.year&lt;br /&gt;
    local month = datein.month&lt;br /&gt;
    local day = datein.day&lt;br /&gt;
    -- jd calculation&lt;br /&gt;
    local a = math.floor((14 - month)/12)&lt;br /&gt;
    local y = year + 4800 - a&lt;br /&gt;
    local m = month + 12*a - 3&lt;br /&gt;
    local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045&lt;br /&gt;
    local jd = day + math.floor((153*m + 2)/5) + 365*y + offset&lt;br /&gt;
    -- jd validation&lt;br /&gt;
    local low, high = -1931076.5, 5373557.49999&lt;br /&gt;
    if not (low &amp;lt;= jd and jd &amp;lt;= high) then&lt;br /&gt;
--    	status.error.msg = &amp;quot;wrong_jd&amp;quot;&lt;br /&gt;
--    	status.error.params = jd&lt;br /&gt;
        return --status&lt;br /&gt;
    end&lt;br /&gt;
	return jd&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- конвертация jd в дату по юлианскому календарю&lt;br /&gt;
function jd2jul( jd )&lt;br /&gt;
	if type(jd) ~= &amp;quot;number&amp;quot; then return error(&amp;quot;Wrong jd&amp;quot;) end&lt;br /&gt;
    -- calendar date calculation&lt;br /&gt;
    local c = jd + 32082&lt;br /&gt;
    local d = math.floor((4*c + 3)/1461)&lt;br /&gt;
    local e = c - math.floor(1461*d/4)&lt;br /&gt;
    local m = math.floor((5*e + 2)/153)&lt;br /&gt;
    local year_out = d - 4800 + math.floor(m/10)&lt;br /&gt;
    local month_out = m + 3 - 12*math.floor(m/10)&lt;br /&gt;
    local day_out = e - math.floor((153*m + 2)/5) + 1&lt;br /&gt;
    -- output&lt;br /&gt;
    local dateout = {[&amp;quot;jd&amp;quot;]=jd, [&amp;quot;year&amp;quot;]=year_out, [&amp;quot;month&amp;quot;]=month_out, [&amp;quot;day&amp;quot;]=day_out,[&amp;quot;calendar&amp;quot;]=&amp;quot;julian&amp;quot;}&lt;br /&gt;
    return dateout&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- конвертация даты по юлианскому календарю в jd&lt;br /&gt;
function jul2jd( datein )&lt;br /&gt;
	if not is_date(datein,true) then &lt;br /&gt;
--		if type(status.error) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
--			status.error = {}&lt;br /&gt;
--		end&lt;br /&gt;
--		status.error.msg = &amp;quot;no_valid_date&amp;quot;&lt;br /&gt;
--		status.error.params = datein&lt;br /&gt;
		return --status &lt;br /&gt;
	end&lt;br /&gt;
    local year = datein.year&lt;br /&gt;
    local month = datein.month&lt;br /&gt;
    local day = datein.day&lt;br /&gt;
    -- jd calculation&lt;br /&gt;
    local a = math.floor((14 - month)/12)&lt;br /&gt;
    local y = year + 4800 - a&lt;br /&gt;
    local m = month + 12*a - 3&lt;br /&gt;
    local offset = math.floor(y/4) - 32083&lt;br /&gt;
    local jd = day + math.floor((153*m + 2)/5) + 365*y + offset&lt;br /&gt;
    -- jd validation&lt;br /&gt;
    local low, high = -1930999.5, 5373484.49999&lt;br /&gt;
    if not (low &amp;lt;= jd and jd &amp;lt;= high) then&lt;br /&gt;
--    	status.error.msg = &amp;quot;wrong_jd&amp;quot;&lt;br /&gt;
--    	status.error.params = jd&lt;br /&gt;
        return --status&lt;br /&gt;
    end&lt;br /&gt;
	return jd&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- конвертация jd в григорианскую дату&lt;br /&gt;
function jd2gri( jd )&lt;br /&gt;
    -- calendar date calculation&lt;br /&gt;
    local a = jd + 32044&lt;br /&gt;
    local b = math.floor((4*a + 3) / 146097)&lt;br /&gt;
    local c = a - math.floor(146097*b/4)&lt;br /&gt;
    local d = math.floor((4*c+3)/1461)&lt;br /&gt;
    local e = c - math.floor(1461*d/4)&lt;br /&gt;
    local m = math.floor((5*e+2)/153)&lt;br /&gt;
    local day_out =  e - math.floor((153*m+2)/5)+1&lt;br /&gt;
    local month_out = m + 3 - 12*math.floor(m/10)&lt;br /&gt;
    local year_out = 100*b + d - 4800 + math.floor(m/10)&lt;br /&gt;
    -- output&lt;br /&gt;
    local dateout = {[&amp;quot;jd&amp;quot;]=jd, [&amp;quot;year&amp;quot;]=year_out, [&amp;quot;month&amp;quot;]=month_out, [&amp;quot;day&amp;quot;]=day_out, [&amp;quot;calendar&amp;quot;]=&amp;quot;gregorian&amp;quot;}&lt;br /&gt;
    return dateout&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- функция для нормализации значений дат и перевода месяцев в числа&lt;br /&gt;
local function numerize(str)&lt;br /&gt;
    if type(str) == &amp;quot;number&amp;quot; then&lt;br /&gt;
        return math.floor(str)&lt;br /&gt;
	elseif str == &amp;quot;&amp;quot; or str == nil or type(str) ~= &amp;quot;string&amp;quot; then&lt;br /&gt;
		return nil&lt;br /&gt;
    elseif type(tonumber(str)) == &amp;quot;number&amp;quot; then&lt;br /&gt;
        return math.floor(tonumber(str))&lt;br /&gt;
    else&lt;br /&gt;
    	for i=1, #lang do&lt;br /&gt;
    		if is_in_list(mw.ustring.lower(str),month_lang[lang[i]]) then&lt;br /&gt;
				return reverse_month_lang[lang[i]][mw.ustring.lower(str)]&lt;br /&gt;
			end&lt;br /&gt;
    	end&lt;br /&gt;
    end&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
-- функция для распознавания дат, заданных тремя значениями подряд, с исправлением ошибок&lt;br /&gt;
local function decode_triple(d,m,y)&lt;br /&gt;
	local year = numerize((y or &amp;quot;&amp;quot;):match(&amp;quot;(%d+)&amp;quot;))&lt;br /&gt;
	local month = numerize(mw.ustring.match((m or &amp;quot;&amp;quot;),&amp;quot;(%a+)&amp;quot;))&lt;br /&gt;
	local day = numerize((d or &amp;quot;&amp;quot;):match(&amp;quot;(%d+)&amp;quot;))&lt;br /&gt;
	if not month then month = numerize(mw.ustring.match((d or &amp;quot;&amp;quot;),&amp;quot;(%a+)&amp;quot;))	end&lt;br /&gt;
	if not day then day = numerize((m or &amp;quot;&amp;quot;):match(&amp;quot;(%d+)&amp;quot;)) end&lt;br /&gt;
	if not year then year = numerize((m or &amp;quot;&amp;quot;):match(&amp;quot;(%d+)&amp;quot;)) end&lt;br /&gt;
	local dateout = {[&amp;quot;year&amp;quot;]=year, [&amp;quot;month&amp;quot;]=month, [&amp;quot;day&amp;quot;]=day}&lt;br /&gt;
	return dateout&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- функция распознавания даты, переданной одной строкой&lt;br /&gt;
local function parse_date(date_string)&lt;br /&gt;
	if type(date_string) ~= &amp;quot;string&amp;quot; or date_string == &amp;quot;&amp;quot; then return nil end&lt;br /&gt;
	local out_date_str = {nil,nil,nil}&lt;br /&gt;
	local error_data = {}&lt;br /&gt;
	for i=1, #pattern do&lt;br /&gt;
		local result_1, result_2, result_3 = mw.ustring.match(date_string,pattern[i][1])&lt;br /&gt;
		if (result_1 or &amp;quot;&amp;quot;) &amp;gt; &amp;quot;&amp;quot; then &lt;br /&gt;
			out_date_str[pattern[i].order[1]], &lt;br /&gt;
    		out_date_str[pattern[i].order[2]], &lt;br /&gt;
    		out_date_str[pattern[i].order[3]] = &lt;br /&gt;
    			result_1, result_2, result_3&lt;br /&gt;
    		break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if (not out_date_str[1]) or (not out_date_str[2]) or (not out_date_str[3]) then&lt;br /&gt;
		error_data.msg = &amp;quot;no_pattern_match&amp;quot;&lt;br /&gt;
		error_data.params = date_string&lt;br /&gt;
	end&lt;br /&gt;
	local date = {&lt;br /&gt;
		[&amp;quot;day&amp;quot;]  =numerize(out_date_str[1]), &lt;br /&gt;
		[&amp;quot;month&amp;quot;]=numerize(out_date_str[2]), &lt;br /&gt;
		[&amp;quot;year&amp;quot;] =numerize(out_date_str[3])}&lt;br /&gt;
	return date, error_data&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- функции для отображения дат в отладочных сообщениях&lt;br /&gt;
local function o(str,arg)&lt;br /&gt;
	return (arg and (arg .. &amp;quot;: &amp;quot;) or &amp;quot;&amp;quot;) .. (str and (bool2num[str] .. &amp;quot; — &amp;quot;) or &amp;quot;&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function unwarp(tbl)&lt;br /&gt;
	if not tbl then return &amp;quot;&amp;quot;&lt;br /&gt;
	elseif type(tbl) ~= &amp;quot;table&amp;quot; then return tbl&lt;br /&gt;
	elseif (tbl.day or tbl.month or tbl.year) then &lt;br /&gt;
		return (tbl.year or &amp;quot;¤&amp;quot;)..&amp;quot;•&amp;quot;..(tbl.month or &amp;quot;¤&amp;quot;)..&amp;quot;•&amp;quot;..(tbl.day or &amp;quot;¤&amp;quot;)&lt;br /&gt;
	else return (tbl[3] or &amp;quot;¤&amp;quot;)..&amp;quot;-&amp;quot;..(tbl[2] or &amp;quot;¤&amp;quot;)..&amp;quot;-&amp;quot;..(tbl[1] or &amp;quot;¤&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function error_output(status)&lt;br /&gt;
	if (status.error.msg or &amp;quot;&amp;quot;) &amp;gt; &amp;quot;&amp;quot; then &lt;br /&gt;
		if type(status.error.params) == &amp;quot;table&amp;quot; and not status.error.params[1] then&lt;br /&gt;
			return errors.start .. string.format(errors[status.error.msg], &lt;br /&gt;
				status.error.params.day or &amp;quot;&amp;quot;, status.error.params.month or &amp;quot;&amp;quot;, &lt;br /&gt;
				status.error.params.year or &amp;quot;&amp;quot;) .. errors.ending&lt;br /&gt;
		elseif type(status.error.params) == &amp;quot;table&amp;quot; and status.error.params[1] then&lt;br /&gt;
			return errors.start .. string.format(errors[status.error.msg], &lt;br /&gt;
				unwarp(status.error.params[1] or &amp;quot;&amp;quot;), unwarp(status.error.params[2] or &amp;quot;&amp;quot;), &lt;br /&gt;
				unwarp(status.error.params[3] or &amp;quot;&amp;quot;)) .. errors.ending&lt;br /&gt;
		else&lt;br /&gt;
			return errors.start .. string.format(errors[status.error.msg],status.error.params or &amp;quot;&amp;quot;) .. errors.ending &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function processing(status,input,max_arg)&lt;br /&gt;
	local first_date_string, second_date_string, category = &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;&lt;br /&gt;
	local first_date, second_date = {}, {}&lt;br /&gt;
	if max_arg &amp;lt;= 3 then&lt;br /&gt;
		first_date_string = table.concat({input[1] or &amp;quot;&amp;quot;, input[2] or &amp;quot;&amp;quot;, input[3] or &amp;quot;&amp;quot;}, &amp;quot; &amp;quot;)&lt;br /&gt;
		first_date, status.error = parse_date(first_date_string)&lt;br /&gt;
		if (status.error.msg or &amp;quot;&amp;quot;) &amp;gt; &amp;quot;&amp;quot; then return status end&lt;br /&gt;
		if is_date(first_date,true) then&lt;br /&gt;
			status.dates, status.processed, status.first_date = 1, true, true&lt;br /&gt;
			return status, first_date&lt;br /&gt;
		else &lt;br /&gt;
			status.dates = 0&lt;br /&gt;
			status.error.msg = &amp;quot;no_valid_date&amp;quot;&lt;br /&gt;
			status.error.params = first_date&lt;br /&gt;
			return status&lt;br /&gt;
		end&lt;br /&gt;
	elseif max_arg &amp;gt; 3 and max_arg &amp;lt;= 6 then&lt;br /&gt;
		if is_complete(input,1,6) then&lt;br /&gt;
			first_date_string = table.concat({input[1], input[2], input[3]}, &amp;quot; &amp;quot;)&lt;br /&gt;
			second_date_string = table.concat({input[4], input[5], input[6]}, &amp;quot; &amp;quot;)&lt;br /&gt;
			first_date, second_date = parse_date(first_date_string), parse_date(second_date_string)&lt;br /&gt;
		else &lt;br /&gt;
			first_date = decode_triple(input[1], input[2], input[3])&lt;br /&gt;
			second_date = decode_triple(input[4], input[5], input[6])&lt;br /&gt;
		end&lt;br /&gt;
		if is_date(first_date,true) then status.first_date = true &lt;br /&gt;
		elseif is_date_part(first_date) then status.first_date = 1 end&lt;br /&gt;
		if is_date(second_date,true) then status.second_date = true &lt;br /&gt;
		elseif is_date_part(second_date) then status.second_date = 1 end&lt;br /&gt;
		if status.first_date == true and status.second_date == true then &lt;br /&gt;
			status.dates, status.processed = 2, true&lt;br /&gt;
		else &lt;br /&gt;
			status.dates = bool2num[status.first_date] + bool2num[status.second_date]&lt;br /&gt;
			status.category = &amp;quot;incomplete_parameters&amp;quot; &lt;br /&gt;
		end&lt;br /&gt;
		return status, first_date, second_date&lt;br /&gt;
	elseif max_arg&amp;gt; 6 then&lt;br /&gt;
		status.error.msg = &amp;quot;too_many_arguments&amp;quot;&lt;br /&gt;
		status.error.params = max_arg&lt;br /&gt;
		return status&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function mix_data(status,first_date,second_date)&lt;br /&gt;
	status.processed = 1&lt;br /&gt;
	for i, k in pairs(time_units) do&lt;br /&gt;
		if not first_date[k] and second_date[k] then &lt;br /&gt;
			first_date[k] = second_date[k]&lt;br /&gt;
		elseif not second_date[k] and first_date[k] then&lt;br /&gt;
			second_date[k] = first_date[k]&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return status, first_date, second_date&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function recalc(status,date,cal)&lt;br /&gt;
	if is_in_list(cal,calendars[1]) then &lt;br /&gt;
		date.jd, date.calendar = gri2jd(date), &amp;quot;gregorian&amp;quot;&lt;br /&gt;
		status.processed, status.second_date, status.dates = true, true, 2&lt;br /&gt;
		return status, date, jd2jul(date.jd) &lt;br /&gt;
	elseif is_in_list(cal,calendars[2]) then&lt;br /&gt;
		date.jd, date.calendar = jul2jd(date), &amp;quot;julian&amp;quot;&lt;br /&gt;
		status.processed, status.second_date, status.dates = true, true, 2&lt;br /&gt;
		return status, date, jd2gri(date.jd)&lt;br /&gt;
	else &lt;br /&gt;
		status.error.msg = &amp;quot;unknown_calendar&amp;quot;&lt;br /&gt;
		status.error.params = cal&lt;br /&gt;
		return status&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function partdist(status,date1,date2)&lt;br /&gt;
	local mont, dist = 0, 0&lt;br /&gt;
	local d1d, d1m, d2d, d2m = date1[&amp;quot;day&amp;quot;], date1[&amp;quot;month&amp;quot;], date2[&amp;quot;day&amp;quot;], date2[&amp;quot;month&amp;quot;]&lt;br /&gt;
	local d1de, d2de = month_end_day(d1m), month_end_day(d2m)&lt;br /&gt;
	if not (number_in_range(d1m,1,12) and number_in_range(d2m,1,12)) then &lt;br /&gt;
		return status, math.huge&lt;br /&gt;
	elseif not (number_in_range(d1d,1,d1de) and number_in_range(d2d,1,d2de)) then &lt;br /&gt;
		return status, math.huge&lt;br /&gt;
	else&lt;br /&gt;
		return status, (d1m == d2m and math.abs(d1d-d2d)) or ((d1d &amp;gt; d2d and (d1de - d1d + d2d)) or (d2de - d2d + d1d))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function guess_jd(status, first_date, second_date)&lt;br /&gt;
--	if not is_date(first_date) or is_date(second_date) then&lt;br /&gt;
--		return status&lt;br /&gt;
--	end&lt;br /&gt;
	local first_j_jd = jul2jd(first_date)&lt;br /&gt;
	local first_g_jd = gri2jd(first_date)&lt;br /&gt;
	local second_j_jd = jul2jd(second_date) &lt;br /&gt;
	local second_g_jd = gri2jd(second_date)&lt;br /&gt;
--	mw.log(first_j_jd,first_g_jd,second_j_jd,second_g_jd)&lt;br /&gt;
	if not first_j_jd or not first_g_jd or not second_j_jd or not second_g_jd then&lt;br /&gt;
		local status, difference = partdist(status,first_date,second_date)&lt;br /&gt;
		status.category = &amp;quot;erroneous_parameters&amp;quot;&lt;br /&gt;
		status.error.msg = &amp;quot;wrong_calculation&amp;quot;&lt;br /&gt;
		status.error.params = {unwarp(first_date),unwarp(second_date),difference}&lt;br /&gt;
	elseif first_j_jd == second_g_jd then&lt;br /&gt;
		first_date.jd, first_date.calendar = first_j_jd, &amp;quot;julian&amp;quot;&lt;br /&gt;
		second_date.jd, second_date.calendar = second_g_jd, &amp;quot;gregorian&amp;quot;&lt;br /&gt;
	elseif first_g_jd == second_j_jd then&lt;br /&gt;
		first_date.jd, first_date.calendar = first_g_jd, &amp;quot;gregorian&amp;quot;&lt;br /&gt;
		second_date.jd, second_date.calendar = second_j_jd, &amp;quot;julian&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		local difference = math.min(math.abs(first_j_jd-second_g_jd),math.abs(first_g_jd-second_j_jd))&lt;br /&gt;
		status.category = &amp;quot;erroneous_parameters&amp;quot;&lt;br /&gt;
		status.error.msg = &amp;quot;wrong_calculation&amp;quot;&lt;br /&gt;
		status.error.params = {unwarp(first_date),unwarp(second_date),difference}&lt;br /&gt;
	end&lt;br /&gt;
	return status, first_date, second_date&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- для записи типа -100 год = 100 год до н.э. (с разрывом в нуле)&lt;br /&gt;
function astroyear(status, num, bc)&lt;br /&gt;
	local year&lt;br /&gt;
	if not num or type(num) ~= &amp;quot;number&amp;quot; then &lt;br /&gt;
		status.error.msg = &amp;quot;tech_error&amp;quot;&lt;br /&gt;
		status.error.params = &amp;quot;astroyear&amp;quot;&lt;br /&gt;
	elseif num &amp;lt; 1 then &lt;br /&gt;
		year = 1 + num &lt;br /&gt;
	end &lt;br /&gt;
	-- todo: запрет нулевого года?&lt;br /&gt;
	if not bc then return status, num&lt;br /&gt;
	else year = 1 - num&lt;br /&gt;
	end&lt;br /&gt;
	return status, year&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- в соответствии с таблицами принимаемых аргументов обрабатывает ввод&lt;br /&gt;
function read_args(status, input)&lt;br /&gt;
	if not status or type(status) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
		status = {}&lt;br /&gt;
		status.error = {}&lt;br /&gt;
		status.error.msg = &amp;quot;tech_error&amp;quot;&lt;br /&gt;
		status.error.params = &amp;quot;read_args&amp;quot;&lt;br /&gt;
	elseif not input or type(input) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
		status.error.msg = &amp;quot;tech_error&amp;quot;&lt;br /&gt;
		status.error.params = &amp;quot;read_args&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		for i,v in pairs(unik_args) do&lt;br /&gt;
			if unik_args_bool[i] then&lt;br /&gt;
				input[v] = is(input[v])&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		for i,v in pairs(dual_args) do&lt;br /&gt;
			if dual_args_bool[i] then&lt;br /&gt;
				local both = is(input[v])&lt;br /&gt;
				if both then&lt;br /&gt;
					input[v..1], input[v..2] = true, true&lt;br /&gt;
				else&lt;br /&gt;
					input[v..1], input[v..2] = is(input[v..1]), is(input[v..2])&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				if input[v] and input[v]&amp;gt;&amp;quot;&amp;quot; then&lt;br /&gt;
					input[v..1], input[v..2] = input[v], input[v]&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if input.ny1 then input.ym1, input.wy1 = nil, false end&lt;br /&gt;
	if input.ny2 then input.ym2, input.wy2 = nil, false end&lt;br /&gt;
	return status, input&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;15&amp;quot;,&amp;quot;августа&amp;quot;,&amp;quot; &amp;quot;,&amp;quot;2&amp;quot;,&amp;quot; &amp;quot;,&amp;quot; &amp;quot;,[&amp;quot;cal&amp;quot;]=&amp;quot;g&amp;quot;,[&amp;quot;wdm2&amp;quot;]=1,[&amp;quot;wy2&amp;quot;]=1}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;15&amp;quot;,&amp;quot;августа&amp;quot;,nil,&amp;quot;2&amp;quot;,[&amp;quot;cal&amp;quot;]=&amp;quot;g&amp;quot;,[&amp;quot;wdm2&amp;quot;]=1,[&amp;quot;wy2&amp;quot;]=1}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;32.1.2020&amp;quot;,[&amp;quot;cal&amp;quot;]=&amp;quot;j&amp;quot;}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;23.12.1855&amp;quot;,[&amp;quot;cal&amp;quot;]=&amp;quot;j&amp;quot;,[&amp;quot;wy2&amp;quot;]=1,[&amp;quot;wdm2&amp;quot;]=1}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;+2017-10-09T00:00:00Z&amp;quot;,[&amp;quot;cal&amp;quot;]=&amp;quot;g&amp;quot;,[&amp;quot;wy&amp;quot;]=1,[&amp;quot;wdm&amp;quot;]=1,[&amp;quot;ny2&amp;quot;]=1,[&amp;quot;sq_brts&amp;quot;]=1,[&amp;quot;ym1&amp;quot;]=&amp;quot;г.&amp;quot;}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;+2017-10-09T00:00:00Z&amp;quot;,[&amp;quot;cal&amp;quot;]=&amp;quot;g&amp;quot;,[&amp;quot;sq_brts&amp;quot;]=true}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;+2017-10-09T00:00:00Z&amp;quot;,[&amp;quot;cal&amp;quot;]=&amp;quot;g&amp;quot;,[&amp;quot;bc&amp;quot;]=1,[&amp;quot;wy&amp;quot;]=1,[&amp;quot;br_in&amp;quot;]=1,[&amp;quot;wdm2&amp;quot;]=1,[&amp;quot;ny1&amp;quot;]=1,}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;+2017-10-09T00:00:00Z&amp;quot;,[&amp;quot;cal&amp;quot;]=&amp;quot;j&amp;quot;}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;30&amp;quot;,&amp;quot;апреля&amp;quot;,nil,&amp;quot;17&amp;quot;}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;30&amp;quot;,&amp;quot;апреля&amp;quot;,&amp;quot;2020&amp;quot;,&amp;quot;17&amp;quot;}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;31&amp;quot;,&amp;quot;апреля&amp;quot;,&amp;quot;2020&amp;quot;}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;23 juin 2020&amp;quot;}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;23 октября 2020&amp;quot;}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;23.10.2020&amp;quot;,cal=&amp;quot;г&amp;quot;}})&lt;br /&gt;
=p.Test(mw.getCurrentFrame():newChild{title=&amp;quot;smth&amp;quot;,args={&amp;quot;2020-10-23&amp;quot;,cal=&amp;quot;ю&amp;quot;}})&lt;br /&gt;
]]--&lt;br /&gt;
function p.Test( frame )&lt;br /&gt;
	-- инициализация, заполнение обратных таблиц, копирование параметров&lt;br /&gt;
	filling_months(lang, month_lang)&lt;br /&gt;
	local args = getArgs(frame, { removeBlanks = false, frameOnly = true })&lt;br /&gt;
	local input, max_arg = copy_it(args)&lt;br /&gt;
&lt;br /&gt;
--	mw.log(&amp;quot;(&amp;quot; .. #input .. &amp;quot;, &amp;quot; .. max_arg .. &amp;quot;)&amp;quot;, unpack(input))&lt;br /&gt;
	-- перевод строковых параметров в числовые&lt;br /&gt;
	input.cal = input.cal or &amp;quot;j&amp;quot;&lt;br /&gt;
	local status, first_date, second_date = {processed=false,first_date=false,second_date=false,category=&amp;quot;&amp;quot;,error={msg=&amp;quot;&amp;quot;,params=&amp;quot;&amp;quot;}}&lt;br /&gt;
	status, first_date, second_date =	processing(status,input,max_arg)&lt;br /&gt;
	-- перевод параметров оформления в булевые&lt;br /&gt;
	status, input = read_args(status, input)&lt;br /&gt;
	&lt;br /&gt;
	-- применение параметра до нашей эры или сдвиг отрицательных дат, чтобы не было разрыва в нулевом году&lt;br /&gt;
	if first_date then status, first_date.year = astroyear(status, first_date.year, input.bc) end&lt;br /&gt;
	if second_date then status, second_date.year = astroyear(status, second_date.year, input.bc) end&lt;br /&gt;
	&lt;br /&gt;
	-- проверка и дополнение дат&lt;br /&gt;
	if (status.dates or 0) &amp;gt; 1 and status.processed ~= true then&lt;br /&gt;
		status, first_date, second_date = mix_data(status,first_date,second_date)&lt;br /&gt;
		status, first_date, second_date = guess_jd(status,first_date,second_date)&lt;br /&gt;
	elseif status.dates == 1 then&lt;br /&gt;
		status, first_date, second_date = recalc(status,first_date,input.cal)&lt;br /&gt;
	elseif max_arg &amp;lt; 3 then&lt;br /&gt;
		if status.error.msg then&lt;br /&gt;
		else&lt;br /&gt;
			status.error.msg = &amp;quot;too_little_arguments&amp;quot;&lt;br /&gt;
			status.error.params = max_arg&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		status.error.msg = &amp;quot;unknown_error&amp;quot;&lt;br /&gt;
		status.error.params = &amp;quot;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--[[ ошибка если даты сформированы не полностью&lt;br /&gt;
	if first_date and not first_date.year and second_date and not second_date.year then &lt;br /&gt;
		error(&amp;quot;Даты &amp;quot; .. unwarp(first_date)  .. &amp;quot; и &amp;quot; .. unwarp(second_date)  .. &amp;quot; не содержат год. &amp;quot; .. &lt;br /&gt;
			(error_output(status) or &amp;quot;&amp;quot;) .. &amp;quot; — &amp;quot; .. &lt;br /&gt;
			(o(status.processed,&amp;quot;processed&amp;quot;) or &amp;quot;&amp;quot;) ..&lt;br /&gt;
			(o(status.first_date,&amp;quot;first_date&amp;quot;) or &amp;quot;&amp;quot;) ..&lt;br /&gt;
			(o(status.second_date,&amp;quot;second_date&amp;quot;) or &amp;quot;&amp;quot;) ..&lt;br /&gt;
			(o(status.category,&amp;quot;category&amp;quot;) or &amp;quot;&amp;quot;))&lt;br /&gt;
	end&lt;br /&gt;
	--]]&lt;br /&gt;
	-- ошибка в случае если даты не сформированы&lt;br /&gt;
	if not first_date or not second_date then return error_output(status) end&lt;br /&gt;
	if     first_date.calendar  == &amp;quot;julian&amp;quot; and second_date.calendar == &amp;quot;gregorian&amp;quot; then&lt;br /&gt;
	elseif second_date.calendar == &amp;quot;julian&amp;quot; and first_date.calendar  == &amp;quot;gregorian&amp;quot; then&lt;br /&gt;
		local swap_date = first_date&lt;br /&gt;
		first_date = second_date&lt;br /&gt;
		second_date = swap_date&lt;br /&gt;
	else&lt;br /&gt;
		status.error.msg = &amp;quot;unknown_error&amp;quot;&lt;br /&gt;
		status.error.params = &amp;quot;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	input.wy1 = first_date.year and input.wy1 or nil&lt;br /&gt;
	input.wy2 = second_date.year and input.wy2 or nil&lt;br /&gt;
	&lt;br /&gt;
--	mw.logObject(input)&lt;br /&gt;
--	mw.logObject(status)&lt;br /&gt;
--	mw.logObject(first_date)&lt;br /&gt;
--	mw.logObject(second_date)&lt;br /&gt;
&lt;br /&gt;
	-- ниже задаются условия поведения кусков текста - в зависимости от каких параметров они принимают какие значения&lt;br /&gt;
	-- если нужно более сложное поведение чем &amp;quot;bool and true_result or false_result&amp;quot;, то их можно заменить на анонимные функции&lt;br /&gt;
	input.lang = input.lang or &amp;quot;ru&amp;quot;&lt;br /&gt;
	local space = snippet:dress{[&amp;quot;text&amp;quot;]= &amp;quot; &amp;quot;, a=0, z=0}&lt;br /&gt;
	local empty = snippet:dress{[&amp;quot;text&amp;quot;]= &amp;quot;&amp;quot;, a=0, z=0}&lt;br /&gt;
	local left = snippet:dress{[&amp;quot;text&amp;quot;] = args.sq_brts and &amp;quot;&amp;amp;#091;&amp;quot; or &amp;quot;(&amp;quot;, [&amp;quot;a&amp;quot;] = 3, [&amp;quot;z&amp;quot;] = 0}&lt;br /&gt;
	local right = snippet:dress{[&amp;quot;text&amp;quot;] = args.sq_brts and &amp;quot;&amp;amp;#093;&amp;quot; or &amp;quot;)&amp;quot;, [&amp;quot;a&amp;quot;] = 0, [&amp;quot;z&amp;quot;] = 3}&lt;br /&gt;
	local bc_mark1 = (first_date.year and first_date.year &amp;lt; 1) and snippet:dress{[&amp;quot;text&amp;quot;]= &amp;quot;до н. э.&amp;quot; } or empty&lt;br /&gt;
	local bc_mark2 = (second_date.year and second_date.year &amp;lt; 1) and snippet:dress{[&amp;quot;text&amp;quot;]=  &amp;quot;до н. э.&amp;quot; } or empty&lt;br /&gt;
	first_date.year = (first_date.year and first_date.year &amp;lt; 1) and -first_date.year or first_date.year&lt;br /&gt;
	second_date.year = (second_date.year and second_date.year &amp;lt; 1) and -second_date.year or second_date.year&lt;br /&gt;
	local jdd, jdm, jdy  = &lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]=first_date.day}, &lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]=month_lang[input.lang][first_date.month]}, &lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]=(input.ny1 or not first_date.year) and &amp;quot;&amp;quot; or first_date.year .. ((input.ym1 and &amp;quot; &amp;quot; or &amp;quot;&amp;quot;) .. (input.ym1 or &amp;quot;&amp;quot;)),&lt;br /&gt;
			a = input.ny1 and 0 or nil, z= input.ny1 and 0 or nil}&lt;br /&gt;
	local gdd, gdm, gdy = &lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]=second_date.day}, &lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]=month_lang[input.lang][second_date.month]}, &lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]=(input.ny2 or not second_date.year) and &amp;quot;&amp;quot; or second_date.year .. ((input.ym2 and &amp;quot; &amp;quot; or &amp;quot;&amp;quot;) .. (input.ym2 or &amp;quot;&amp;quot;)),&lt;br /&gt;
			a = input.ny2 and 0 or nil, z= input.ny2 and 0 or nil}&lt;br /&gt;
		&lt;br /&gt;
	local wdm1_, wdm2_, wy1_, wy2_ =&lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]= input.wdm1 and table.concat{&lt;br /&gt;
			&amp;quot;[[&amp;quot;, jdd.text,&amp;quot; &amp;quot;,jdm.text ,&amp;quot;|&amp;quot;} or &amp;quot;&amp;quot;, a=input.wdm1 and 2 or 0, z=0},&lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]= input.wdm2 and table.concat{&lt;br /&gt;
			&amp;quot;[[&amp;quot;, gdd.text,&amp;quot; &amp;quot;,gdm.text ,&amp;quot;|&amp;quot;} or &amp;quot;&amp;quot;, a=input.wdm2 and 2 or 0, z=0},&lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]= (input.wy1 and first_date.year) and (&amp;quot;[[&amp;quot; .. first_date.year .. &amp;quot; год&amp;quot; .. &lt;br /&gt;
			(bc_mark1.text &amp;gt; &amp;quot;&amp;quot; and (&amp;quot; &amp;quot; .. bc_mark1.text) or &amp;quot;&amp;quot;) .. &amp;quot;|&amp;quot;) or &amp;quot;&amp;quot;, a=input.wy1 and 2 or 0, z=0},&lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]= (input.wy2 and second_date.year) and (&amp;quot;[[&amp;quot; .. second_date.year .. &amp;quot; год&amp;quot; .. &lt;br /&gt;
			(bc_mark2.text &amp;gt; &amp;quot;&amp;quot; and (&amp;quot; &amp;quot; .. bc_mark2.text) or &amp;quot;&amp;quot;) .. &amp;quot;|&amp;quot;) or &amp;quot;&amp;quot;, a=input.wy2 and 2 or 0, z=0}&lt;br /&gt;
	local wdm_1, wdm_2, wy_1, wy_2 =&lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]= input.wdm1 and &amp;quot;]]&amp;quot; or &amp;quot;&amp;quot;, a=0, z=input.wdm1 and 2 or 0},&lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]= input.wdm2 and &amp;quot;]]&amp;quot; or &amp;quot;&amp;quot;, a=0, z=input.wdm2 and 2 or 0},		&lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]= input.wy1 and &amp;quot;]]&amp;quot; or &amp;quot;&amp;quot;, a=0, z=input.wy1 and 2 or 0},&lt;br /&gt;
		snippet:dress{[&amp;quot;text&amp;quot;]= input.wy2 and &amp;quot;]]&amp;quot; or &amp;quot;&amp;quot;, a=0, z=input.wy2 and 2 or 0}	&lt;br /&gt;
	local cdm, cdy = empty, empty&lt;br /&gt;
	&lt;br /&gt;
	input.order = input.order or &amp;quot;zip&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
	if input.order == &amp;quot;zip&amp;quot; then&lt;br /&gt;
		if first_date.month == second_date.month then&lt;br /&gt;
			cdm = mw.clone(jdm)&lt;br /&gt;
			jdm, gdm = empty, empty&lt;br /&gt;
		end&lt;br /&gt;
		if first_date.year == second_date.year then&lt;br /&gt;
			cdy = mw.clone(jdy)&lt;br /&gt;
			jdy, gdy = empty, empty&lt;br /&gt;
			cdy = wy2_ + cdy + bc_mark2 + wy_2&lt;br /&gt;
			wy1_, wy_1 = empty, empty&lt;br /&gt;
			wy2_, wy_2 = empty, empty&lt;br /&gt;
			bc_mark1, bc_mark2 = empty, empty&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local j_day_month = wdm1_ + jdd + jdm + wdm_1&lt;br /&gt;
	local j_year = wy1_ + jdy + bc_mark1 + wy_1&lt;br /&gt;
	local g_day_month = wdm2_ + gdd + gdm + wdm_2&lt;br /&gt;
	local g_year = wy2_ + gdy + bc_mark2 + wy_2&lt;br /&gt;
&lt;br /&gt;
	if input.order == &amp;quot;full&amp;quot; then&lt;br /&gt;
		return mw.text.trim(tostring(j_day_month + j_year + left + g_day_month + g_year + right))&lt;br /&gt;
	elseif input.order == &amp;quot;zip&amp;quot; then&lt;br /&gt;
		return mw.text.trim(tostring(j_day_month + j_year + left + g_day_month + g_year + right  + cdm + cdy))&lt;br /&gt;
	else&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if status.error then &lt;br /&gt;
		return error_output(status) &lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
--	todo - part date dist check, year mark from double triplets, julian span comment, br_in?, check if format table is full, add short formats d.m.y - 1/01&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Andras</name></author>
	</entry>
</feed>