Module:Sandbox/Artbarte/Dates

From English Wikipedia @ Freddythechick
-- Artbarte Google Code-in, Date formatting
-- WIP

local p = {}

-- Checks if string is a format and returns format string
-- Takes string | returns format string to be applied to os.date() OR nil
function parseFormat(str)
	local formats = {mdy = "%B %d, %Y",year = "%Y",iso = "%Y-%m-%d",dmy = "%d %B %Y"}
	formats["month and year"] = "%B %Y"
	
	return formats[str]
end

-- Checks if string is a month or month abbreviation
-- Takes string | returns integer of month OR nil
function parseMonth(str)
	str = string.lower(str)
	local months = {{"January","jan"},
					{"February","feb"},
					{"March","mar"},
					{"April","apr"},
					{"May","may"},
					{"June","jun"},
					{"July","jul"},
					{"August","aug"},
					{"September","sep"},
					{"October","oct"},
					{"November","nov"},
					{"December","dec"},
					}
					
	for i,v in ipairs(months) do
		if str == string.lower(v[1]) or str == v[2] then
			return i
		end
	end
	return nil
end
-- Checks if the string includes on of the "circa words"
function checkIfCirca (str)
	local dateString = str
	local circa = false
	
	local circaStrings = {"%(uncertain%)", "sometime ", "around "}
	for i,v in ipairs(circaStrings) do
		dateString, matches = string.gsub(dateString , v, "")
		if  matches >= 1 then
			circa = true
		end
	end
	return circa, dateString
	end

p.parseDate = function (frame)
	local date = frame.args.date or ""
	local format = frame.args.format or ""
	
	-- 
	local circa = false
	circa, date = checkIfCirca(date)
	
	-- Pattern searches for 3 words sperated by spaces, slashes or dashes and puts them into variables: first, second, third
	local first,second,third = string.match(date, "([%w%d]+)[ /-]([%w%d]+)[, /-] ?(%d+)")

	-- If pattern didn't find any proper date format display error message
	local fields = {}
	if first ~= nil then table.insert(fields,first) else return "Invalid input <br>" end
	if second ~= nil then table.insert(fields,second) end
	if third ~= nil then table.insert(fields,third) end
	
	-- Putting fields into proper value
	local day,month,year
	for i,v in ipairs(fields) do
		local parsedMonth = parseMonth(v)
		if parsedMonth ~= nil then
			month = parsedMonth
		elseif tonumber(v) > 31 then -- year only
			year = v
		elseif tonumber(v) > 12 then -- day only
			day = v
		elseif month == nil then
			month = v
		else
			day = v
		end
	end
	
	-- Preparing the return message
	local returnMsg = date
	
	-- If format is specified 
	parsedFormat = parseFormat(format)
	if parsedFormat ~= nil then
		local time = os.time({month=month,day=day,year=year})
		returnMsg = os.date(parsedFormat, time)
	end
	
	if circa then 
	 	returnMsg = "circa " .. returnMsg
	end
	-- Return the message
	return "Input: ".. date .. " Format: " .. format .. "<br>Output: '''" .. returnMsg .. "'''<br>"
end

return p