Изменения

обновление
Строка 1: Строка 1:  +
local p = {}
 +
-- Необходимые модули
 
local getArgs = require('Module:Arguments').getArgs
 
local getArgs = require('Module:Arguments').getArgs
local formatWikiImpl = require('Module:Dates temp').formatWikiImpl
+
local yesno = require('Module:Yesno')
local p = {}
+
local err = "―" -- NthDay nil result
local err = "-"
+
-- 00) Блок многократно используемых списков
 
local bool_to_number={ [true]=1, [false]=0 }
 
local bool_to_number={ [true]=1, [false]=0 }
 
local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}
 
local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}
local griglist = {"г", "g"}
+
local params = { {"г", "g"}, {"ю", "j"},  {"нэ", "НЭ", "ac", "AC"}, {"днэ", "ДНЭ", "bc", "BC"}}
local julilist = {"ю", "j"}
+
local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'}
local yearmark = ""
+
local known_tzs = {
local bcmark = "до н. э."
+
  ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT  ='-03:00', AEDT ='+11:00',
 +
  AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00',
 +
  AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST  ='+04:00', AST  ='+03:00',
 +
  AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT  ='+04:00',
 +
  BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT  ='-04:00', BRT  ='-03:00',
 +
  BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT  ='+02:00', CCT  ='+06:30',
 +
  CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET  ='+01:00', CHAST='+12:45',
 +
  CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT  ='-04:00', COST ='-04:00',
 +
  COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT  ='-01:00', CXT  ='+07:00',
 +
  CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT  ='+03:00', ECT  ='-04:00',
 +
  ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET  ='+02:00',
 +
  EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT  ='-04:00', GALT ='-06:00',
 +
  GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT  ='-09:00', GMT  ='+00:00',
 +
  GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT  ='+08:00',
 +
  HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST  ='+05:30',
 +
  IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST  ='+09:00',
 +
  LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT  ='-06:00', MIT  ='-09:30',
 +
  MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST  ='-07:00', MST  ='+06:30',
 +
  MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT  ='+05:45', NST  ='-03:30',
 +
  NT  ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00',
 +
  PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET  ='+04:00', SAMT ='+04:00',
 +
  SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT  ='+05:30', SST  ='-11:00',
 +
  SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC  ='+00:00', UYST ='-02:00',
 +
  UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT  ='+01:00', WEDT ='+01:00',
 +
  WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00', MSK  ='+03:00',
 +
  -- US Millitary (for RFC-822)
 +
  Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00',
 +
}
 +
 
 +
local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST",
 +
"AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT",
 +
"BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST",
 +
"CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT",
 +
"CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT",
 +
"FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST",
 +
"HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST",
 +
"LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT",
 +
"NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT",
 +
"SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET",
 +
"VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"}
 +
 
 +
-- 10) Блок общих функций
 +
local function trim(str)
 +
if not str then return nil
 +
else return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)'
 +
end
 +
end
    
local function purif(str)
 
local function purif(str)
Строка 19: Строка 67:  
     end
 
     end
 
     -- need .5 -- ,5 number format converter?
 
     -- need .5 -- ,5 number format converter?
 +
end
 +
 +
local function is(str)
 +
if (not str) or (str == "") then return false
 +
else return yesno(str,false)
 +
end
 
end
 
end
   Строка 29: Строка 83:  
end
 
end
   −
function p.NthDay( frame )
+
function shallowcopy(orig)
     local args = getArgs(frame, { frameOnly = true })
+
     local orig_type = type(orig)
     local num, wday, mont, yea, format =
+
     local copy
    purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5]
+
     if orig_type == 'table' then
if not format then format = "%d.%m.%y" end
+
         copy = {}
     if not inbord(num,-5,5) then
+
         for orig_key, orig_value in pairs(orig) do
    return error("The number must be between -5 and 5")
+
             copy[orig_key] = orig_value
    elseif num == 0 then
  −
    return error("The number must not be zero") end
  −
    if not inbord(wday,0,6) then
  −
    return error("The day of the week must be between 0 and 6") end
  −
    if not inbord(mont,1,12) then
  −
    return error("The month must be between 1 and 12") end
  −
    if not inbord(yea,0,9999) then
  −
    return error("Wrong year number") end
  −
    if inbord(num,1,5) then
  −
         local m_start = os.time{year=yea, month=mont, day=1, hour=0}
  −
         local m_wds = tonumber(os.date("%w", m_start))
  −
        local start_shift = (
  −
            (num - bool_to_number[wday >= m_wds]) * 7
  −
            - (m_wds - wday)
  −
            ) * 24 * 60 * 60
  −
        local tim = m_start + start_shift
  −
        if tonumber(os.date("%m", tim)) == mont then
  −
             return (os.date(format, tim))
  −
        else
  −
            return (err)
  −
        end
  −
    elseif inbord(num,-5,-1) then
  −
        local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60
  −
        local m_wde = tonumber(os.date("%w", m_end))
  −
        local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7
  −
            + (m_wde - wday)) * 24 * 60 * 60
  −
        local tim = m_end - end_shift
  −
        if tonumber(os.date("%m", tim)) == mont then
  −
            return (os.date(format, tim))
  −
        else
  −
            return (err)
   
         end
 
         end
 +
    else -- number, string, boolean, etc
 +
        copy = orig
 
     end
 
     end
 +
    return copy
 
end
 
end
 +
 +
local inlist = function ( var, list )
 +
    local n = #list
 +
local inlist = false
 +
for i=1,n do
 +
if var == list[i] then inlist = true end
 +
end
 +
    return inlist
 +
end
 +
 +
-- 20) Блок общих проверочных функций, связанных с датами
    
local function isdate ( chain )
 
local function isdate ( chain )
if (not type(chain) == "table")
+
if not chain then return false
 +
elseif (not type(chain) == "table")
 
or (not inbord(chain.year,-9999,9999))
 
or (not inbord(chain.year,-9999,9999))
 
or (not inbord(chain.month,1,12))
 
or (not inbord(chain.month,1,12))
Строка 84: Строка 122:     
local function ispartdate ( chain )
 
local function ispartdate ( chain )
if not (type(chain) == "table") then return false
+
if not chain then return false
 +
elseif not (type(chain) == "table") then return false
 
elseif (inbord(chain.year,-9999,9999)
 
elseif (inbord(chain.year,-9999,9999)
 
and (not inbord(chain.month,1,12))
 
and (not inbord(chain.month,1,12))
Строка 98: Строка 137:  
end
 
end
   −
local islist = function ( var, list )
+
-- 30) Блок функций для обработки ввода-вывода дат
    local n = #list
  −
local inlist = false
  −
for i=1,n do
  −
if var == list[i] then inlist = true end
  −
end
  −
    return inlist
  −
end
     −
local function numstr2date(numstr)
+
local numstr2date = function(numstr)
 
local nums = {}
 
local nums = {}
 
     local dateout = {}
 
     local dateout = {}
Строка 129: Строка 161:  
end
 
end
   −
local function date2str(datein)
+
local function year2lang(numyear,yearmark,wiki)
if not isdate(datein) then return error("Wrong date") end
+
if not numyear then return "" end
local dateout = os.date("%Y-%m-%d", os.time(datein))
+
if not yearmark then yearmark = "" end
    return dateout
+
local output = ""
 +
local bcmark = " до н. э."
 +
if numyear > 0 then bcmark = ""
 +
else numyear = 1 - numyear end
 +
if wiki then
 +
output = table.concat({'[[', numyear,' год',bcmark,'|', numyear,']]', " ", yearmark, " ", bcmark})
 +
else
 +
output = table.concat({numyear, " ", yearmark, bcmark})
 +
end
 +
return trim(output)
 
end
 
end
 
+
local function date2lang(datein)
+
local function day2lang(datein,wikidate,wiki,inner_brt)
if not ispartdate(datein) then return error("Wrong partial date") end
+
-- if not isdate(wikidate) then wiki = false end
local dm_separ = ""
+
if not ispartdate(datein) then return "" end
local my_separ = ""
+
local dm_separ, output = ""
local monlan = ""
  −
local era = ""
   
if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end
 
if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end
if (not (not datein.month)) and (not (not datein.year)) then my_separ = " " end
  −
if not datein.year then datein.year = ""
  −
elseif datein.year == "" then
  −
elseif datein.year < 1 then
  −
local negyear = datein.year
  −
datein.year = 1 - negyear
  −
era = yearmark .. " " .. bcmark
  −
else datein.year = datein.year .. yearmark
  −
end
   
if (not datein.month) then datein.month = "" end
 
if (not datein.month) then datein.month = "" end
 
if (not datein.day) then datein.day = "" end
 
if (not datein.day) then datein.day = "" end
if type(my_separ) ~= "string" or type(dm_separ) ~= "string" then error("Separator fail to work") end
+
local monlan = monthlang[datein.month] or ""
if (not datein.month) or (datein.month == "") then
+
if wiki and not inner_brt then
else monlan = monthlang[datein.month] end
+
output = table.concat({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
local dateout = datein.day .. dm_separ .. monlan .. my_separ .. datein.year .. era
+
"|", (datein.day or ""), dm_separ, monlan, "]]"})
     return dateout
+
elseif wiki then
 +
output = table.concat({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
 +
"|", (datein.day or ""), dm_separ, monlan})
 +
else
 +
output = table.concat({datein.day, dm_separ, monlan})
 +
end
 +
     return trim(output)
 
end
 
end
   −
function trim(str)
+
local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
  return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)'
+
local cd = {}
 +
local jd = shallowcopy(jdate)
 +
local gd = shallowcopy(gdate)
 +
local left = "("
 +
local right = ")"
 +
if sq_brts then
 +
left = "&#091;"
 +
right = "&#093;"
 +
end
 +
if (not isdate(jdate)) or (not isdate(gdate)) then return error("Some wrong date") end
 +
if jd.year == gd.year then
 +
cd.year = gd.year
 +
gd.year, jd.year = nil
 +
end
 +
if jd.month == gd.month then
 +
cd.month = gd.month
 +
gd.month, jd.month = nil
 +
end
 +
if (not not cd.month) and wm then
 +
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,
 +
day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy))}, " ")
 +
end
 +
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(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy))}, " ")
 
end
 
end
   −
local function twodates2str(jdate,gdate)
+
-- 40) Блок функций для перевода дат с использованием [[Юлианская дата]]
if (not isdate(jdate)) or (not isdate(gdate)) then return error("Some wrong date")
  −
else
  −
local cdate = {}
  −
if jdate.year == gdate.year then
  −
cdate.year = jdate.year
  −
jdate.year = ""
  −
gdate.year = ""
  −
end
  −
if jdate.month == gdate.month then
  −
cdate.month = jdate.month
  −
jdate.month = ""
  −
gdate.month = ""
  −
end
  −
local ending = ""
  −
if ispartdate(cdate) then ending = " " .. date2lang(cdate) end
  −
local output = '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">' .. trim(date2lang(jdate)) .. "</span> (" .. trim(date2lang(gdate)) .. ")" .. ending
  −
return output
  −
end
  −
end
      
function gri2jd( datein )
 
function gri2jd( datein )
Строка 254: Строка 296:  
end
 
end
   −
function p.gri2jul( frame )
+
function astroyear(num, bc)
    local args = getArgs(frame, { frameOnly = true })
+
if not bc then return num
    local datein = args[1]
+
else return 1 - num
    -- парсинг входящей даты по шаблону
+
end
    local pattern = "(%d+)%.(%d+)%.(%d+)"
  −
    local dayin, monthin, yearin = datein:match(pattern)
  −
    local year = tonumber(yearin)
  −
    local month = tonumber(monthin)
  −
    local day = tonumber(dayin)
  −
    -- проверка параметров
  −
    if not (type(year) == 'number') then
  −
        return error("Wrong year")
  −
    end
  −
    if not (1 <= month and month <= 12) then
  −
        return error("Wrong month")
  −
    end
  −
    if not (1 <= day and day <= 31) then
  −
        return error("Wrong day")
  −
    end
  −
    -- расчёт юлианской даты
  −
    local a = math.floor((14 - month)/12)
  −
    local y = year + 4800 - a
  −
    local m = month + 12*a - 3
  −
    local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045
  −
    local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
  −
    -- проверка попадания юлианской даты в границы между -9999 и 9999 годами Ю.К.
  −
    local low, high = -1931076.5, 5373557.49999
  −
    if not (low <= jd and jd <= high) then
  −
        return error("Wrong date")
  −
    end
  −
    -- расчёт даты по юлианскому календарю
  −
    local c = jd + 32082
  −
    local d = math.floor((4*c + 3)/1461)
  −
    local e = c - math.floor(1461*d/4)
  −
    local m = math.floor((5*e + 2)/153)
  −
    local year_out = d - 4800 + math.floor(m/10)
  −
    local month_out = m + 3 - 12*math.floor(m/10)
  −
    local day_out = e - math.floor((153*m + 2)/5) + 1
  −
    -- вывод даты в формате ГГГГ-ММ-ДД
  −
    local date = os.date("%Y-%m-%d", os.time{year=year_out, month=month_out, day=day_out})
  −
    return date
  −
end
  −
 
  −
function p.jul2gri( frame )
  −
    local args = getArgs(frame, { frameOnly = true })
  −
    local datein = args[1]
  −
    -- парсинг входящей даты по шаблону
  −
    local pattern = "(%d+)%.(%d+)%.(%d+)"
  −
    local dayin, monthin, yearin = datein:match(pattern)
  −
    local year = tonumber(yearin)
  −
    local month = tonumber(monthin)
  −
    local day = tonumber(dayin)
  −
    -- проверка параметров
  −
    if not (type(year) == 'number') then
  −
        return error("Wrong year")
  −
    end
  −
    if not (1 <= month and month <= 12) then
  −
        return error("Wrong month")
  −
    end
  −
    if not (1 <= day and day <= 31) then
  −
        return error("Wrong day")
  −
    end
  −
    -- расчёт юлианской даты
  −
    local a = math.floor((14 - month)/12)
  −
    local y = year + 4800 - a
  −
    local m = month + 12*a - 3
  −
    local offset = math.floor(y/4) - 32083
  −
    local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
  −
    -- проверка попадания юлианской даты в границы -9999 до 9999 года Г.К.
  −
    local low, high = -1930999.5, 5373484.49999
  −
    if not (low <= jd and jd <= high) then
  −
        return error("Wrong date")
  −
    end
  −
    -- расчёт даты по григорианскому календарю
  −
    local a = jd + 32044
  −
    local b = math.floor((4*a + 3) / 146097)
  −
    local c = a - math.floor(146097*b/4)
  −
    local d = math.floor((4*c+3)/1461)
  −
    local e = c - math.floor(1461*d/4)
  −
    local m = math.floor((5*e+2)/153)
  −
    local day_out =  e - math.floor((153*m+2)/5)+1
  −
    local month_out = m + 3 - 12*math.floor(m/10)
  −
    local year_out = 100*b + d - 4800 + math.floor(m/10)
  −
    local date = os.date("%Y-%m-%d", os.time{year=year_out, month=month_out, day=day_out})
  −
    return date
  −
end
  −
 
  −
function p.ToIso( frame )
  −
    local args = getArgs(frame, { frameOnly = true })
  −
    local datein = args[1]
  −
    -- парсинг входящей даты по шаблону
  −
    local pattern = "(%d+)%.(%d+)%.(%d+)"
  −
    local dayin, monthin, yearin = datein:match(pattern)
  −
    local year = tonumber(yearin)
  −
    local month = tonumber(monthin)
  −
    local day = tonumber(dayin)
  −
    -- проверка параметров
  −
    if not (type(year) == 'number') then
  −
        return error("Wrong year")
  −
    end
  −
    if not (1 <= month and month <= 12) then
  −
        return error("Wrong month")
  −
    end
  −
    if not (1 <= day and day <= 31) then
  −
        return error("Wrong day")
  −
    end
  −
    local timedate = os.time{year=year, month=month, day=day}
  −
    local date = os.date("%Y-%m-%d", timedate)
  −
    return date
   
end
 
end
   −
function p.ToDate( frame )
+
function recalc(datein,calend)
    local args = getArgs(frame, { frameOnly = true })
+
if inlist(calend,params[1]) then
    local lang = mw.getContentLanguage()
+
return jd2jul(gri2jd(datein)), datein
    local datein = args[1]
+
  elseif inlist(calend,params[2]) then
    local format = "j xg Y"
+
return datein, jd2gri(jul2jd(datein))
    if not string.match(datein, "%p") then return datein
+
  else error("Second argument must be 'g' or 'j'")
    elseif not args[2] then
+
  end
    else format = args[2]
  −
    end
  −
    return lang:formatDate(format,datein,true)
   
end
 
end
   −
local known_tzs = {
+
-- 50) Функции для обработки UTC
  ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT  ='-03:00', AEDT ='+11:00',
  −
  AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00',
  −
  AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST  ='+04:00', AST  ='+03:00',
  −
  AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT  ='+04:00',
  −
  BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT  ='-04:00', BRT  ='-03:00',
  −
  BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT  ='+02:00', CCT  ='+06:30',
  −
  CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET  ='+01:00', CHAST='+12:45',
  −
  CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT  ='-04:00', COST ='-04:00',
  −
  COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT  ='-01:00', CXT  ='+07:00',
  −
  CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT  ='+03:00', ECT  ='-04:00',
  −
  ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET  ='+02:00',
  −
  EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT  ='-04:00', GALT ='-06:00',
  −
  GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT  ='-09:00', GMT  ='+00:00',
  −
  GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT  ='+08:00',
  −
  HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST  ='+05:30',
  −
  IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST  ='+09:00',
  −
  LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT  ='-06:00', MIT  ='-09:30',
  −
  MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST  ='-07:00', MST  ='+06:30',
  −
  MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT  ='+05:45', NST  ='-03:30',
  −
  NT  ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00',
  −
  PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET  ='+04:00', SAMT ='+04:00',
  −
  SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT  ='+05:30', SST  ='-11:00',
  −
  SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC  ='+00:00', UYST ='-02:00',
  −
  UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT  ='+01:00', WEDT ='+01:00',
  −
  WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00', MSK  ='+03:00',
  −
  -- US Millitary (for RFC-822)
  −
  Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00',
  −
}
  −
 
  −
local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST",
  −
"AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT",
  −
"BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST",
  −
"CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT",
  −
"CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT",
  −
"FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST",
  −
"HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST",
  −
"LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT",
  −
"NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT",
  −
"SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET",
  −
"VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"}
      
local function utc(str,margin)
 
local function utc(str,margin)
Строка 476: Строка 370:  
end
 
end
   −
-- =p.test(mw.getCurrentFrame():newChild{title="smth",args={"11.02.2020","1.2.2020"}})
+
-- 60) Блок функций ввода-вывода
   −
function p.test( frame )
+
function p.NthDay( frame )
local args = getArgs(frame, { frameOnly = true })
+
    local args = getArgs(frame, { frameOnly = true })
     local jstrin, gstrin = args[1], args[2]
+
     local num, wday, mont, yea, format =  
local jdat = numstr2date(jstrin)
+
    purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5]
local gdat = numstr2date(gstrin)
+
if not format then format = "%d.%m.%y" end
     return formatWikiImpl(jdat,gdat)
+
    if not inbord(num,-5,5) then
 +
    return error("The number must be between -5 and 5")
 +
    elseif num == 0 then
 +
    return error("The number must not be zero") end
 +
    if not inbord(wday,0,6) then
 +
    return error("The day of the week must be between 0 and 6") end
 +
    if not inbord(mont,1,12) then
 +
    return error("The month must be between 1 and 12") end
 +
    if not inbord(yea,0,9999) then
 +
    return error("Wrong year number") end
 +
    if inbord(num,1,5) then
 +
        local m_start = os.time{year=yea, month=mont, day=1, hour=0}
 +
        local m_wds = tonumber(os.date("%w", m_start))
 +
        local start_shift = (
 +
            (num - bool_to_number[wday >= m_wds]) * 7
 +
            - (m_wds - wday)
 +
            ) * 24 * 60 * 60
 +
        local tim = m_start + start_shift
 +
        if tonumber(os.date("%m", tim)) == mont then
 +
            return (os.date(format, tim))
 +
        else
 +
            return (err)
 +
        end
 +
    elseif inbord(num,-5,-1) then
 +
        local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60
 +
        local m_wde = tonumber(os.date("%w", m_end))
 +
        local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7
 +
            + (m_wde - wday)) * 24 * 60 * 60
 +
        local tim = m_end - end_shift
 +
        if tonumber(os.date("%m", tim)) == mont then
 +
            return (os.date(format, tim))
 +
        else
 +
            return (err)
 +
        end
 +
    end
 +
end
 +
 
 +
function p.ToIso( frame ) -- возможно неиспользуемая
 +
    local args = getArgs(frame, { frameOnly = true })
 +
    local datein = args[1]
 +
    -- парсинг входящей даты по шаблону
 +
    local pattern = "(%d+)%.(%d+)%.(%d+)"
 +
    local dayin, monthin, yearin = datein:match(pattern)
 +
    local year = tonumber(yearin)
 +
    local month = tonumber(monthin)
 +
    local day = tonumber(dayin)
 +
    -- проверка параметров
 +
    if not (type(year) == 'number') then
 +
        return error("Wrong year")
 +
    end
 +
    if not (1 <= month and month <= 12) then
 +
        return error("Wrong month")
 +
    end
 +
    if not (1 <= day and day <= 31) then
 +
        return error("Wrong day")
 +
    end
 +
    local timedate = os.time{year=year, month=month, day=day}
 +
    local date = os.date("%Y-%m-%d", timedate)
 +
    return date
 +
end
 +
 
 +
function p.ToDate( frame ) -- возможно неиспользуемая
 +
    local args = getArgs(frame, { frameOnly = true })
 +
    local lang = mw.getContentLanguage()
 +
    local datein = args[1]
 +
    local format = "j xg Y"
 +
    if not string.match(datein, "%p") then return datein
 +
    elseif not args[2] then
 +
    else format = args[2]
 +
    end
 +
     return lang:formatDate(format,datein,true)
 
end
 
end
   Строка 496: Строка 460:  
     local input = args[1]
 
     local input = args[1]
 
     if not input then return "" end
 
     if not input then return "" end
     if islist(input:upper(),tzs_names) then  
+
     if inlist(input:upper(),tzs_names) then  
 
     utcin = known_tzs[input:upper()]  
 
     utcin = known_tzs[input:upper()]  
 
     elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then
 
     elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then
Строка 520: Строка 484:  
end
 
end
   −
--  =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю","днэ","1","0"}})
+
--  =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["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"]="г."}})
 
-- function p.formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix, brts )
 
-- 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 })
 
     local gdate, jdate = {}
 
     local gdate, jdate = {}
     local output = ""
+
     local strin = args[1]
     local strin = args[1]
+
     local cal = args[2]:lower() or "г"
     local calinp = "г"
+
     local bc = is(args["bc"])
     if not args[2] then else calinp = args[2]:lower() end
+
     local wd = is(args["wd"])
     local era = "нэ"
+
    local wm = is(args["wm"])
     if not args[3] then else era = args[3]:lower() end
+
     local wy = is(args["wy"])
     local wiki = false
+
     if not wd then wm = false end
     if not args[4] then else wiki = true end
+
    local sq_brts = is(args["sq_brts"])
--  local brts = nil
+
     local yearmark = "года"
--  if not args[5] then else brts = true end
+
     if yesno(args["yearmark"]) then
--  local infocardClass = nil
+
    elseif yesno(args["yearmark"]) == false then yearmark = ""
--  local categoryNamePrefix = nil
+
    else yearmark = trim(args["yearmark"]) or "года" end
 +
--  local infocard = is(args["infocard"])
 +
--  local catName = args["catName"] or false
 
     local datein = numstr2date(strin)
 
     local datein = numstr2date(strin)
     if era == "нэ" then
+
     datein.year = astroyear(datein.year, bc)
if islist(calinp,griglist) then
+
    jdate, gdate = recalc(datein,cal)
gdate = datein
+
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
    jdate = jd2jul(gri2jd(gdate))
  −
    elseif islist(calinp,julilist) then
  −
jdate = datein
  −
    gdate = jd2gri(jul2jd(jdate))
  −
    else error("Second argument must be 'g' or 'j'")
  −
    end
  −
elseif era == "днэ" then
  −
local negyear = datein.year
  −
datein.year = 1 - negyear
  −
if islist(calinp,griglist) then
  −
gdate = datein
  −
    jdate = jd2jul(gri2jd(gdate))
  −
    elseif islist(calinp,julilist) then
  −
jdate = datein
  −
    gdate = jd2gri(jul2jd(jdate))
  −
    else error("Second argument must be 'g' or 'j'")
  −
    end
  −
end
  −
if wiki then output = formatWikiImpl(jdate,gdate) --,infocardClass,categoryNamePrefix,brts
  −
else output = twodates2str(jdate, gdate) end
  −
    return output
   
end
 
end
    
return p
 
return p
Анонимный участник