Module:Sandbox/Userring/Dates

Revision as of 17:49, 23 January 2020 by imported>Userring
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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