Изменения

обновление
Строка 3: Строка 3:  
local getArgs = require('Module:Arguments').getArgs
 
local getArgs = require('Module:Arguments').getArgs
 
local yesno = require('Module:Yesno')
 
local yesno = require('Module:Yesno')
 +
local lang = mw.getContentLanguage()
 
local err = "―" -- NthDay nil result
 
local err = "―" -- NthDay nil result
 +
 
-- 00) Блок многократно используемых списков
 
-- 00) Блок многократно используемых списков
 
local bool_to_number={ [true]=1, [false]=0 }
 
local bool_to_number={ [true]=1, [false]=0 }
 
local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}
 
local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}
 +
local month_to_num = {["января"]=1,["февраля"]=2,["марта"]=3,["апреля"]=4,["мая"]=5,["июня"]=6,
 +
["июля"]=7,["августа"]=8,["сентября"]=9,["октября"]=10,["ноября"]=11,["декабря"]=12,["-"]=""}
 
local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
 
local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
local params = { {"г", "g"}, {"ю", "j"} }
+
local params = { {"г", "g"}, {"ю", "j"}}
 
local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'}
 
local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'}
 +
local category = {["params"]="<!--[[Категория:Модуль:calendar:Страницы с некорректными параметрами]]-->"}
 +
 
local known_tzs = {
 
local known_tzs = {
 
   ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT  ='-03:00', AEDT ='+11:00',
 
   ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT  ='-03:00', AEDT ='+11:00',
Строка 73: Строка 79:  
if (not str) or (str == "") then return false
 
if (not str) or (str == "") then return false
 
else return yesno(str,false)
 
else return yesno(str,false)
 +
end
 +
end
 +
 +
local function init(num)
 +
output = {}
 +
for i=1,num do
 +
table.insert(output, {["year"]="", ["month"]="", ["day"]=""})
 +
end
 +
return unpack(output)
 +
end
 +
 +
local function isyear(tbl)
 +
if type(tbl) ~= 'table' then return false
 +
elseif not tbl["year"] then return false
 +
elseif type(tbl["year"]) == 'number' then return true
 +
else return false
 
end
 
end
 
end
 
end
Строка 138: Строка 160:  
if not chain then return false
 
if not chain then return false
 
elseif not (type(chain) == "table") then return false
 
elseif not (type(chain) == "table") then return false
elseif (inbord(chain.year,-9999,9999)
  −
and (not inbord(chain.month,1,12))
  −
and inbord(chain.day,1,31)) then return false
   
elseif (inbord(chain.year,-9999,9999)
 
elseif (inbord(chain.year,-9999,9999)
 
or inbord(chain.month,1,12)
 
or inbord(chain.month,1,12)
Строка 149: Строка 168:  
--  more detailed check for 31.02.0000 needed
 
--  more detailed check for 31.02.0000 needed
 
--  check for other calendars needed
 
--  check for other calendars needed
 +
end
 +
 +
-- from date1 to date2 in one year (beetwen jan-dec, dec-jan needed)
 +
local function partdist(date1,date2)
 +
local mont, dist = 0, 0
 +
local d1d, d1m, d2d, d2m = (date1["day"] or ""), (date1["month"] or ""),(date2["day"] or ""), (date2["month"] or "")
 +
if not (inbord(d1d,1,31) and inbord(d2d,1,31)) then return false end
 +
-- нужна доп. проверка частичных дат на корректность
 +
if (inbord(d1m,1,12) or inbord(d2m,1,12))
 +
and (d1m == "" or d2m == "") then
 +
mont = purif(date1["month"] or date2["month"])
 +
d1m, d2m = mont, mont
 +
end
 +
-- mw.log("📏 day: " ..d1d .."->"..d2d.." month: ".. d1m.."->"..d2m )
 +
if (inbord(d1m,1,12) and d1d <= monthd[d1m])
 +
and (inbord(d2m,1,12) and d2d <= monthd[d2m]) then
 +
if d2m == d1m
 +
then dist = d2d - d1d
 +
else dist = monthd[d1m] - d1d + d2d
 +
end
 +
return dist
 +
else return math.huge
 +
end
 +
end
 +
 +
local function dmdist(d1,d2)
 +
local p1,p2 = math.huge,math.huge
 +
if not not partdist(d1,d2) then
 +
p1=partdist(d1,d2)
 +
end
 +
if not not partdist(d2,d1) then
 +
p1=partdist(d2,d1)
 +
end
 +
-- if (not p1) or (not p2) then
 +
-- return  (p1 or "") .. (p2 or "")
 +
-- else
 +
-- mw.log("d1, d2 = " .. undate(d1) .. ", " .. undate(d2))
 +
return math.min(tonumber(partdist(d1,d2)) or math.huge,tonumber(partdist(d2,d1)) or math.huge)
 +
-- end
 
end
 
end
    
-- 30) Блок функций для обработки ввода-вывода дат
 
-- 30) Блок функций для обработки ввода-вывода дат
    +
local function undate(tbl)
 +
if not tbl then return ""
 +
else return (tbl.year or "").."-"..(tbl.month or "").."-"..(tbl.day or "")
 +
end
 +
end
 +
 +
----[[ УСТАРЕЛО ]]----
 
local numstr2date = function(numstr)
 
local numstr2date = function(numstr)
local nums = {}
+
local lang = mw.getContentLanguage()
    local dateout = {}
+
local format = "Y-m-d"
    for num in string.gmatch(numstr,"(%d+)") do
+
local iso_date = lang:formatDate(format,numstr)
        table.insert(nums,purif(num))
+
    local y,m,d = string.match(iso_date, "(%d+)-(%d+)-(%d+)")
    end
+
local dateout = {["year"]=purif(y), ["month"]=purif(m), ["day"]=purif(d)}
    if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums)
+
    return dateout
    elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден")
+
end
    elseif not inbord(nums[3],1,31) then
+
--local numstr2date = function(numstr)
        dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
+
-- local nums = {}
    elseif not inbord(nums[1],1,31) then
+
--    local dateout = {}
        dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]}
+
--    for num in string.gmatch(numstr,"(%d+)") do
    elseif inbord(nums[1],1,31) then
+
--        table.insert(nums,purif(num))
        dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
+
--    end
    else
+
--    if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums)
 +
--    elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден")
 +
--    elseif not inbord(nums[3],1,31) then
 +
--        dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
 +
--    elseif not inbord(nums[1],1,31) then
 +
--        dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]}
 +
--    elseif inbord(nums[1],1,31) then
 +
--        dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
 +
--    else
 
-- local lang = mw.getContentLanguage()
 
-- local lang = mw.getContentLanguage()
 
-- implement lang:formatDate(format,datein,true) here
 
-- implement lang:formatDate(format,datein,true) here
        return error("Не распознано " .. numstr .. " как дата")
+
--        return error("Не распознано " .. numstr .. " как дата")
    end
+
--    end
    return dateout
+
--    return dateout
end
+
--end
    
local function year2lang(numyear,yearmark,wiki)
 
local function year2lang(numyear,yearmark,wiki)
Строка 209: Строка 282:  
end
 
end
 
     return trim(output)
 
     return trim(output)
 +
end
 +
 +
local function triple_txt2date(d,m,y)
 +
-- добавить (args[1]:match("(%a+)") or "-") для нестандартной записи
 +
-- mw.ustring.match((m or ""),"(%a+)")
 +
local msg = ""
 +
local year = purif((y or "-"):match("(%d+)"))
 +
local month = purif(month_to_num[string.lower(mw.ustring.match((m or ""),"(%a+)"))])
 +
local day = purif((d or "-"):match("(%d+)"))
 +
if not month then
 +
msg = category["params"]
 +
month = purif(month_to_num[string.lower(mw.ustring.match((d or ""),"(%a+)") or "-")])
 +
end
 +
if (not day) and ((purif(string.match(m or "","(%d+)") or "") or 32) <= (monthd[month] or 31)) then
 +
msg = category["params"]
 +
day = purif(m:match("(%d+)") or "")
 +
end
 +
if not year then
 +
msg = category["params"]
 +
year = purif(string.match(m or "","(%d+)") or "")
 +
end
 +
local dateout = {["year"]=year, ["month"]=month, ["day"]=day, ["msg"]=msg}
 +
return dateout
 +
end
 +
 +
local function glue(d1,m1,y1,d2,m2,y2)
 +
if (not d1) and (not m1) and (not y1) and (not d2) and (not m2) and (not y2) then
 +
return category["params"] end
 +
local gd,gm,gy,jd,jm,jy =
 +
(d1 or ""),
 +
(m1 or ""),
 +
(y1 or ""),
 +
(d2 or ""),
 +
(m2 or ""),
 +
(y2 or "")
 +
--mw.log(table.concat({gd,gm,gy,jd,jm,jy}))
 +
return table.concat({comment[1],trim(trim(jd .. " " .. jm) .. " " .. jy ),
 +
comment[2]," ([[",trim(gd .. " " .. gm),"]] [[",(gy:match("(%d+)") or ""),
 +
" год|",gy,"]])",category["params"]})
 
end
 
end
    
-- добавить отображение без года
 
-- добавить отображение без года
 
local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
 
local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
 +
local msg = ""
 +
msg = (jdate.msg or "") .. (gdate.msg or "")
 
local cd = {}
 
local cd = {}
 
local jd = shallowcopy(jdate)
 
local jd = shallowcopy(jdate)
Строка 222: Строка 336:  
right = "&#093;"
 
right = "&#093;"
 
end
 
end
if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата")  
+
if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата")
 
elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end
 
elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end
 
if jd.year == gd.year then
 
if jd.year == gd.year then
Строка 235: Строка 349:  
return table.concat({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],  
 
return table.concat({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],  
 
trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,  
 
trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,  
day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy))}, " ")
+
day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
 
end  
 
end  
 
return table.concat({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],  
 
return table.concat({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],  
 
trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,  
 
trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,  
trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy))}, " ")
+
trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
 
end
 
end
   Строка 506: Строка 620:  
end
 
end
   −
-- добавить различные типы викификации одним str аргументом
+
 
-- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"29.02.2100","ю",["bc"]="0",["wd"]="1",["wy"]="0",["sq_brts"]="0"}})
+
-- УСТАРЕЛО
 
-- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
 
-- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
-- function p.formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix, brts )
   
function p.OldDate( frame )
 
function p.OldDate( frame )
 
     local args = getArgs(frame, { frameOnly = true })
 
     local args = getArgs(frame, { frameOnly = true })
Строка 534: Строка 647:  
end
 
end
    +
-- =p.NewDate(mw.getCurrentFrame():newChild{title="Salt",args={"2020-02-20"}})
 +
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
 
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}})
 
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}})
 
function p.NewDate( frame )
 
function p.NewDate( frame )
Строка 551: Строка 666:  
if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy")
 
if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy")
 
end
 
end
local jdate = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)}
  −
local gdate = jd2gri(jul2jd(jdate))
   
 
 
local bc,wd,wm,wy,sq_brts =  
 
local bc,wd,wm,wy,sq_brts =  
Строка 560: Строка 673:  
is(args["wy"]),
 
is(args["wy"]),
 
is(args["sq_brts"])
 
is(args["sq_brts"])
   
+
 
 +
year = astroyear(purif(year),bc)
 +
 
 +
local jdate = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)}
 +
local gdate = jd2gri(jul2jd(jdate))
 +
 
 
     local yearmark = "года"
 
     local yearmark = "года"
 
     local ym = args["yearmark"] or ""
 
     local ym = args["yearmark"] or ""
Строка 572: Строка 690:  
      
 
      
 
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
 
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
 +
end
 +
 +
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={}})
 +
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня",nil,"21","мая"}})
 +
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","","1916 года","15"}})
 +
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня","1900","21","мая"}})
 +
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"6","июня","1889 год","25","мая"}})
 +
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28","ноября","1917","15"}})
 +
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","nil","1916 года","15"}})
 +
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"4","января","1915","22","декабря","1914 года"}})
 +
-- {{OldStyleDate|день (НС)|месяц (НС)|год (НС)|день (СС)|месяц (СС)|год (СС)}}
 +
 +
function p.Test( frame )
 +
local args = getArgs(frame, { frameOnly = true })
 +
-- необходима проверка и замена nil на " "
 +
--[[mw.log((args[1] or "") .. " " ..
 +
(args[2] or "") .. " " ..
 +
(args[3] or "") .. " " ..
 +
(args[4] or "") .. " " ..
 +
(args[5] or "") .. " " ..
 +
(args[6] or "")) ]]--
 +
local ingdate = triple_txt2date(args[1],args[2],args[3])
 +
local injdate = triple_txt2date(args[4],args[5],args[6])
 +
local j1date, g1date, j2date, g2date = init(4)
 +
mw.log("ingdate-".. (undate(ingdate) or ""))
 +
mw.log("injdate-".. (undate(injdate) or ""))
 +
local bc,wd,wm,wy,sq_brts,ny =
 +
is(args["bc"]),
 +
is(args["wd"]),
 +
is(args["wd"]) and is(args["wm"]),
 +
is(args["wy"]),
 +
is(args["sq_brts"]),
 +
is(args["ny"])
 +
-- подавление формата для локальных тестов
 +
    local wd, wm, wy = true, true, true
 +
   
 +
    local yearmark = "года"
 +
    local ym = args["yearmark"] or ((mw.ustring.match((args[3] or ""),"(%a+)") or mw.ustring.match((args[6] or ""),"(%a+)")) or "")
 +
    -- mw.log("ym " .. ym)
 +
    if yesno(ym) then
 +
    elseif yesno(ym) == false then yearmark = ""
 +
    else
 +
    if not not ym:match("(%d+)") then
 +
    error("Цифры в обозначении года: " .. ym)
 +
    else yearmark = trim(ym) or "года" end
 +
    end
 +
    if isdate(ingdate) or isdate(injdate) then
 +
if isdate(ingdate) then
 +
j1date, g1date = recalc(ingdate,"g")
 +
ingdate["full"] = true
 +
end
 +
if isdate(injdate) then
 +
j2date, g2date = recalc(injdate,"j")
 +
injdate["full"] = true
 +
end
 +
if ispartdate(ingdate) and ispartdate(injdate) then
 +
mw.log("📏 " .. dmdist(ingdate,injdate))
 +
mw.log("📏 " .. dmdist(j1date,g1date))
 +
mw.log("📏 " .. dmdist(j2date,g2date))
 +
mw.log("📏 " .. dmdist(ingdate,g1date))
 +
mw.log("📏 " .. dmdist(injdate,j2date))
 +
end
 +
end
 +
 +
if ny then
 +
if isyear(j1date) then
 +
else j1date["year"] = "" end
 +
if isyear(j2date) == nil then
 +
else j2date["year"] = "" end
 +
if isyear(g1date) == nil then
 +
else g1date["year"] = "" end
 +
if isyear(g2date) == nil then
 +
else g2date["year"] = "" end
 +
end
 +
if (isdate(j1date) and isdate(g1date) and isdate(j2date) and isdate(g2date)) then
 +
if ((j1date.year == j2date.year)
 +
and (j1date.month == j2date.month)
 +
and (j1date.day == j2date.day)) then
 +
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark)
 +
else
 +
mw.log("📏 " .. (tostring(dmdist(ingdate,injdate)) or ""))
 +
return glue(args[1],args[2],args[3],args[4],args[5],args[6]) 
 +
-- категория (предположительная разница в днях) и частичный вывод
 +
end
 +
elseif isdate(j1date) and isdate(g1date) then
 +
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
 +
elseif isdate(j2date) and isdate(g2date) then
 +
return double_couple(j2date, g2date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
 +
elseif (ispartdate(ingdate) and ispartdate(injdate)) then
 +
mw.log("ingdate ".. (undate(ingdate) or ""))
 +
mw.log("injdate ".. (undate(injdate) or ""))
 +
mw.log("j1date " .. (undate(j1date ) or ""))
 +
mw.log("j2date " .. (undate(j2date ) or ""))
 +
mw.log("g1date " .. (undate(g1date ) or ""))
 +
mw.log("g2date " .. (undate(g2date ) or ""))
 +
mw.log("📏 " .. (tostring(partdist(ingdate,injdate)) or "").. " — " .. (tostring(partdist(injdate,ingdate)) or ""))
 +
return glue(args[1],args[2],args[3],args[4],args[5],args[6])
 +
-- частичный или полный вывод, категория
 +
else
 +
mw.log("ingdate ".. (undate(ingdate) or ""))
 +
mw.log("injdate ".. (undate(injdate) or ""))
 +
mw.log("j1date " .. (undate(j1date ) or ""))
 +
mw.log("j2date " .. (undate(j2date ) or ""))
 +
mw.log("g1date " .. (undate(g1date ) or ""))
 +
mw.log("g2date " .. (undate(g2date ) or ""))
 +
return err .. category["params"]
 +
end
 
end
 
end
    
return p
 
return p
Анонимный участник