Documentation for this module may be created at Module:Sandbox/Userring/Dates/doc
-- Userring Google Code In
-- Lua Task 9 - Date formats
p = {}
function p.getdate(frame)
-- Function to get a date from a given text
-- Getting inputs of the text and format
local instring = frame.args.text or ""
local given_outformat = frame.args.format or ""
local given_outvalue = 0
local text_format = ""
local text_format_value = 0
-- Assigning general variables which will be later used in the code
local months = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
local mplace, month_number, d, m, y = 0, 0, 0, 0
local certainty = nil
-- Functions for processes that are repetitively executed.
local function get_month_from_text()
possible_months = {}
for possible_month in string.gmatch(instring, "%a+") do
unchanged_mon = possible_month
mon_tocheck = string.lower(possible_month)
mon_tocheck_1 = string.sub(mon_tocheck, 1, 1)
mon_tocheck_rest = string.sub(mon_tocheck, 2)
mon_tocheck = string.sub(string.upper(mon_tocheck_1) .. mon_tocheck_rest, 1, 3)
for i=1, table.getn(months) do
checking_against = string.sub(months[i], 1, 3)
if mon_tocheck == checking_against then
month_number = i
mplace = string.find(instring, unchanged_mon)
return true
end
end
end
return false
end
local function verify_date()
-- Function to verify that the date exists
max_date = 0
d, month_number, y = tonumber(d), tonumber(month_number), tonumber(y)
if month_number == 4 or month_number == 6 or month_number == 9 or month_number == 11 then
max_date = 30
elseif month_number == 2 then
if y%400 == 0 or (y%100 ~= 0 and y%4 == 0) then
max_date = 29
else
max_date = 28
end
else
max_date = 31
end
if d > max_date then
return false
else
return true
end
end
local function get_output()
-- Function to return the output
certainty = string.find(instring, "uncertain") or string.find(instring, "around")
if certainty == nil then
certainty = ""
else
certainty = "circa "
end
addition = ""
if string.find(instring, "AD") then
addition = "AD"
elseif string.find(instring, "BC") then
addition = "BC"
elseif string.find(instring, "BCE") then
addition = "BCE"
elseif string.find(instring, "CE") then
addition = "CE"
end
if text_format == "mdy" then
verified = verify_date()
if verified == false then
return "Invalid entry."
else
if month_number == 0 then
m = months[tonumber(m)]
return certainty .. m .. " " .. d .. ", " .. y .. " " .. addition
else
return certainty .. months[tonumber(month_number)] .. " " .. d .. ", " .. y .. " " .. addition
end
end
elseif text_format == "dmy" then
verified = verify_date()
if verified == false then
return "Invalid entry."
else
if month_number == 0 then
m = months[tonumber(m)]
return certainty .. d .. " " .. m .. " " .. y .. " " .. addition
else
return certainty .. d .. " " .. months[tonumber(month_number)] .. " " .. y .. " " .. addition
end
end
elseif text_format == "my" then
return certainty .. m .. " " .. y .. " " .. addition
elseif text_format == "year" then
return certainty .. y .. " " .. addition
elseif text_format == "iso" then
if month_number == 0 then
return certainty .. y .. "-" .. m .. "-" .. d .. " " .. addition
else
return certainty .. y .. "-" .. month_number .. "-" .. d .. " " .. addition
end
elseif text_format == "Invalid" then
return "Invalid entry"
end
end
local function verify_format()
-- Function to verify the format given
if given_outformat == "dmy" then
given_outvalue = 3
return true
elseif given_outformat == "mdy" then
given_outvalue = 3
return true
elseif given_outformat == "iso" then
given_outvalue = 3
return true
elseif given_outformat == "my" then
given_outvalue = 2
return true
elseif given_outformat == "year" then
given_outvalue = 1
return true
elseif given_outformat == "" or given_outformat == nil then
return true
else
return false
end
end
-- Checking if inputs are valid
checked_format = verify_format()
if checked_format == false then
return "Invalid Entry."
end
if instring == "" or instring == nil then
return "Invalid Entry."
end
local function get_y()
-- Function to get the year
y_tocheck = {}
for pos_y in string.gmatch(instring, "%d+") do
table.insert(y_tocheck, tonumber(pos_y))
end
if table.getn(y_tocheck) == 0 then
text_format, text_format_value = "Invalid", 0
elseif table.getn(y_tocheck) == 1 then
text_format, text_format_value = "year", 1
y = y_tocheck[1]
else
pos_y = y_tocheck[table.maxn(y_tocheck)]
if tonumber(pos_y) > 31 then
text_format, text_format_value = "year", 1
y = pos_y
else
text_format, text_format_value = "Invalid", 0
end
end
end
-- Checking if the date is in an ISO format.
iso_1, iso_2, iso_3 = string.match(instring, "(%d+)%p(%d+)%p(%d+)")
-- If not, the date is the in format mdy, dmy, my or year
if iso_1 == nil or iso_2 == nil or iso_3 == nil then
month_checked = get_month_from_text()
if month_checked == false then
get_y()
elseif month_checked == true then
m = months[month_number]
local pos_d_string = string.sub(instring, 1, mplace)
for pos in string.gmatch(pos_d_string, "%d+") do
if tonumber(pos) <= 31 then
d = tonumber(pos)
end
end
if d > 0 and not(m == nil) then
text_format, text_format_value = "dmy", 3
local pos_dy_string = string.sub(instring, mplace)
y = string.match(pos_dy_string, "%d+")
if y == nil then
return "Invalid entry."
end
elseif d == 0 and not(m == nil) then
pos_comma_place = string.find(instring, ",")
if pos_comma_place == nil then
text_format, text_format_value = "my", 2
local pos_my_string = string.sub(instring, mplace)
y = string.match(pos_my_string, "%d+")
else
text_format, text_format_value = "mdy", 3
local pos_y_string = string.sub(instring, tonumber(pos_comma_place))
y = string.match(pos_y_string, "%d+")
local pos_d_string = string.sub(instring, mplace, pos_comma_place)
local pos_d = string.match(pos_d_string, "%d+")
if tonumber(pos_d) <= 31 then
d = tonumber(pos_d)
end
end
elseif m == nil then
m = 0
get_y()
end
end
else
text_format, text_format_value = "iso", 3
m = iso_2
if tonumber(iso_1) > 31 then
y = iso_1
d = iso_3
elseif tonumber(iso_3) > 31 then
y = iso_3
d = iso_1
end
end
if given_outformat == "" or given_outformat == nil then
return get_output()
else
if given_outvalue < text_format_value then
return "Invalid Entry."
elseif given_outvalue <= text_format_value then
text_format = given_outformat
return get_output()
end
end
end
return p