Module:DatesWD
Appearance
local p = {}
local bool_to_number={ [true]=1, [false]=0 }
local getArgs = require('Module:Arguments').getArgs
local err = ""
function p.NthDay( frame )
local args = getArgs(frame, { frameOnly = true })
local num = math.floor(tonumber(args[1]))
local wday = math.floor(tonumber(args[2]))
local mont = math.floor(tonumber(args[3]))
local yea = math.floor(tonumber(args[4]))
local format = args[5]
local bool_to_number={ [true]=1, [false]=0 }
local err = "---"
if num < -5 or num > 5 then
error("The number must be between -5 and 5")
elseif num == 0 then
error("The number must not be zero")
end
if wday < 0 or wday > 6 then
error("The day of the week must be between 0 and 6") end
if mont < 0 or mont > 12 then
error("The month must be between 1 and 12") end
if yea < 0 or yea > 9999 then
error("Wrong year number") end
if num > 0 and num < 6 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 num < 0 and num > -6 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
local purif = function (str)
if str == "" or str == nil then
return nil
elseif type(tonumber(str)) == "number" then
return math.floor(tonumber(str))
else
return nil
end
-- need .5 -- ,5 number format converter
error("You shouldn't read this")
end
local inbord = function (val, down, up)
if type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up then
return false
else
return true
end
end
local inborders = function (val, down, up)
if up < down or type(up) ~= "number" or type(down) ~= "number" then
err = "Range " .. down .. "-" .. up .. " is not valid."
return error(err)
elseif type(val) ~= "number" then
err = "Value " .. val .. " is not valid"
return error(err)
elseif val < down or val > up then
err = "Value " .. val .. " not in the " .. down .. "-" .. up .. " range."
return error(err)
else
return val
end
end
local str2date = function (datein)
local nums = {}
local dateout = {}
for num in string.gmatch(datein,"(%d+)") do
table.insert(nums,purif(num))
end
mw.log((unpack(nums)))
if #nums ~= 3 then error("Wrong format: 3 numbers expected")
elseif not inbord(nums[2],1,12) then error("Wrong month")
elseif not inbord(nums[1],1,31) then
dateout.year = nums[3]
dateout.month = nums[2]
dateout.day = nums[1]
elseif not inbord(nums[3],1,31) then
dateout.year = nums[1]
dateout.month = nums[2]
dateout.day = nums[3]
else
error("Unable to recognize date format")
end
return dateout
end
-- =p.test(mw.getCurrentFrame():newChild{title="обычно не важно",args={"1.1.2020"}})
function p.test(frame)
local args = getArgs(frame, { frameOnly = true })
local input = args[1]
if not input then
return ""
else
return unpack(str2date(input))
end
error("You shouldn't read this too")
end
return p