Thank you very much! Could some moderator please move this thread to there then?
EDIT: A few more small-but-really-useful functions:
table.size(table)
Returns the table size. Works better than #table (because this one counts strings too, not only integers)
Code: Select all
function table.size(t)
local s = 0
for i, v in pairs(t) do
s = s + 1
end
return s
end
table.contains(table, entry)
Returns the table position if it finds the entry, false otherwise.
Code: Select all
function table.contains(t, e)
for i, v in pairs(t) do
if v == e then
return i
end
end
return false
end
table.copy(table, copyInsideTables)
Returns an exact equal copy of a table. Optionally, the tables inside it too.
Code: Select all
function table.copy(t, s) --s for tables inside table
local s = s or false
if not t then
return {}
end
local returner = {}
for i, v in pairs(t) do
if s and type(v) == "table" then
returner[i] = table.copy(v, true)
else
returner[i] = v
end
end
return returner
end
round(number, decimal values)
Much like the well-known round function, I just made it simpler...
Code: Select all
function round(n, r)
local r = r or 0
return math.floor(n*10^r)/10^r
end
toboolean(string)
Pretty obvious...
Code: Select all
function toboolean(s)
if s == "true" then
return true
elseif s == "false" then
return false
elseif s == "nil" then
return nil
else
error("Attempted to convert " .. s .. " to boolean")
end
end
isLeapYear(year)
Returns true if it is a leap year, and false otherwise. Only works for Gregorian calendar, I think.
Code: Select all
function isLeapYear(y)
if math.mod(y, 400) == 0 then
return true
elseif math.mod(y, 4) == 0 and math.mod(y, 100) ~= 0 then
return true
end
return false
end
validDay(month, day, year)
Returns true if the date exists, false otherwise. Requires "isLeapYear".
Code: Select all
function validDay(m, d, y)
local mon = m
local day = d
local year = y
local maxmon = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
local can = true
if type(day) ~= "number" or type(mon) ~= "number" or type(year) ~= "number" then
can = false
elseif mon == 2 and day == 29 and isLeapYear(year) == false then
can = false
elseif day > maxmon[mon] then
can = false
elseif day < 1 or mon < 1 or year < 1800 then --before 1800 is completely unneeded
can = false
elseif mon > 12 or year > 3000 then --after it? Who will use this after it?
can = false
elseif math.mod(day, 1) ~= 0 or math.mod(mon, 1) ~= 0 or math.mod(year, 1) ~= 0 then
can = false
end
return can
end
weekDay(day string)
As it says, it gets the week day of a date (or false if fails). Day strings are formatted like "mm/dd/yyyy". Requires "validDay" function.
Code: Select all
function weekDay(s, a)
local week = {"sun", "mon", "tue", "wed", "thu", "fri", "sat"}
local weeki = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}
local t = s:split("/")
for i = 1, 3 do
t[i] = tonumber(t[i]) or false
end
local mon = t[1]
local day = t[2]
local year = t[3]
local can = validDay(mon, day, year)
if can then
if a then
return weeki[os.date("%w", os.time{day=day, month=mon, year=year})+1]
else
return week[os.date("%w", os.time{day=day, month=mon, year=year})+1]
end
else
print("Error: " .. s .. " is not a valid day")
return false
end
end
before(date1, date2)
Returns true if date1 comes BEFORE date2. Dates are formatted like "mm/dd/yyyy".
Code: Select all
function before(a, b)
local at = a:split("/")
local bt = b:split("/")
local m1 = tonumber(at[1])
local d1 = tonumber(at[2])
local y1 = tonumber(at[3])
local m2 = tonumber(bt[1])
local d2 = tonumber(bt[2])
local y2 = tonumber(bt[3])
if d1 < d2 and m1 <= m2 and y1 <= y2 then
return true
elseif d1 >= d2 and m1 < m2 and y1 <= y2 then
return true
elseif d1 >= d2 and y1 < y2 then
return true
elseif y1 < y2 then
return true
end
return false
end
after(date1, date2)
Returns true if date1 comes AFTER date2. Dates are formatted like "mm/dd/yyyy". Requires "before".
Code: Select all
function after(a, b)
if a == b then
return false
else
return not before(b, a)
end
end
string:fill(size, position, character)
Fills the string with the specified character until it gets from the same size specified. An example: "12":fill(5, "start", "0") returns "00012". Not sure if this one requires "class.lua" because of "self" things...
Code: Select all
function string:fill(sz, pos, ch) --Inspired by Maurice, re-made by me
local n = self
local ch = ch or "0"
local pos = pos or "start"
if string.len(n) >= sz then
return n
else
if pos == "before" or pos == "start" or pos == "beginning" then
while string.len(n) < sz do
n = ch .. n
end
elseif pos == "after" or pos = "end" or pos == "ending" then
while string.len(n) < sz do
n = n .. ch
end
end
end
return n
end
lastDay(date)
Returns the day that came before "date", or empty if fails. Dates are formatted like "mm/dd/yyyy". Requires "string:fill", "validDay" and "isLeapYear".
Code: Select all
function lastDay(s)
local t = s:split("/")
local mon = tonumber(t[1])
local day = tonumber(t[2])
local year = tonumber(t[3])
if validDay(mon, day, year) == false then
return ""
end
local maxmon = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
if day == 1 then
if mon == 1 then
if year == 1800 then
return ""
else
year = year - 1
mon = 12
day = maxmon[mon]
end
else
mon = mon - 1
day = maxmon[mon]
if mon == 2 and isLeapYear(year) then
day = 29
end
end
else
day = day - 1
end
local nd = tostring(day)
local nm = tostring(mon)
local ny = tostring(year)
return nm:fill(2) .. "/" .. nd:fill(2) .. "/" .. ny
end
nextDay(date)
Returns the day that came after "date", or empty if fails. Dates are formatted like "mm/dd/yyyy". Requires "string:fill", "validDay" and "isLeapYear".
Code: Select all
function nextDay(s)
local t = s:split("/")
local mon = tonumber(t[1])
local day = tonumber(t[2])
local year = tonumber(t[3])
if validDay(mon, day, year) == false then
return ""
end
local maxmon = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
if dia == maxmon[mon] and not (day == 28 and mon == 2 and isLeapYear(year)) then
if mon == 12 then
if year == 3000 then
return ""
else
year = year + 1
mon = 1
day = 1
end
else
mon = mon + 1
day = 1
end
else
day = day + 1
end
local nd = tostring(day)
local nm = tostring(mon)
local ny = tostring(year)
return nm:fill(2) .. "/" .. nd:fill(2) .. "/" .. ny
end
And, once again, just so it gets more useful and less out-of-place,
could some moderator please move this to "General"? It fits better there, and I don't want to make two threads for it, it's a waste of space... Thank you