Documentation for this module may be created at Module:Sandbox/Kid116/Dates/doc

local p = {}
function p.Dates (frame)
	input = mw.text.trim(frame.args[1])
	input = " " .. input .. " "
	xformat = frame.args.format or 0
	xsuffix = frame.args.suffix or 0
	
	hasDate = 0
	hasMonth = 0
	hasYear = 0
	
	year = 0
	month = 0
	xdate = 0
	
	specialSuffix = 0
	
	ly = 0
	
	valid = 1
	
	txt = ""
	
	a = 0
	b = 0
	
	p.yr ()
	
	if hasYear~=0 then
		if input:find ("%d%d%p%d%d%p%d%d%d%d") or input:find ("%d%d%d%d%p%d%d%p%d%d") then
			p.isoType ()
		else
			p.Monthss ()
			p.Date ()
		end
	else
		p.Monthss ()
		if hasMonth~=0 then 
			p.Date ()
		else
			if input:find ("%s%d%d%s") then
				if input:find ("AD") or input:find ("BC") or input:find ("CE") or input:find ("BCE") then
					year = tonumber(string.sub(input, input:find ("%s%d%d%s")+1, input:find ("%s%d%d%s")+2))
					a = 1
				end
			else
				valid = 0
			end
		end
	end
	if hasYear then
		p.leapYear ()
	end
	p.validation()
	
	if a == 1 then valid = 1 end

	if valid ~= 0 then 
		if xsuffix == 0 then
			if input:find ("AD") or input:find ("BC") or input:find ("CE") or input:find ("BCE") then
				if year ~= 0 then
					if input:find ("AD") then xsuffix = "AD" end 
					if input:find ("BC") then xsuffix = "BE" end 
					if input:find ("CE") then xsuffix = "CE" end 
					if input:find ("BCE") then xsuffix = "BCE" end 
				end
			end
		end	
		if xsuffix ~= 0 then
			p.suffixes ()
		else
			if xformat == 0 then
				xformat = "dmy"
				if input:find (",") then xformat = "mdy" end
				if input:find ("-") or input:find ("/") then xformat = "iso" end
			end
			if xdate == 0 and month == 0 and year ~= 0 then xformat = "year" end
			if xdate ~= 0 and month == 0 and year ~= 0 then xformat = "year" end
			p.formats ()
		end	
		if specialSuffix then
			p.sSuffixes ()
		end
	else
		txt = "Invalid entry. "
	end
	return txt .. " "
end
function p.yr ()
	if input:find ("%s%d%d%d%s") then
		hasYear = 1
		year = string.sub(input, input:find ("%s%d%d%d%s") + 1, input:find ("%s%d%d%d%s") + 3)
	end
	if input:find ("%s%d%d%d%d%s") then
		hasYear = 1
		year = string.sub(input, input:find ("%s%d%d%d%d%s") + 1, input:find ("%s%d%d%d%d%s") + 4)
	end
	if input:find ("%p%d%d%d%d%s") then
		hasYear = 1
		year = string.sub(input, input:find ("%p%d%d%d%d%s") + 1, input:find ("%p%d%d%d%d%s") + 4)
	end
	if input:find ("%s%d%d%d%d%p") then
		hasYear = 1
		year = string.sub(input, input:find ("%s%d%d%d%d%p") + 1, input:find ("%s%d%d%d%d%p") + 4)
	end
	year = tonumber(year)
end
function p.sSuffix()
	if input:find ("uncertain") or input:find ("sometime") or input:find ("around") then
		if input:find ("uncertain who") then
			specialSuffix = 2
		else
			specialSuffix = 1
		end
	end
	if input:find ("lord") and input:find ("year") then
		specialSuffix = 3
	end
end
function p.isoType()
	if input:find ("%d%d%p%d%d%p%d%d%d%d") then
		temp1 = tonumber(string.sub(input, input:find ("%d%d%p%d%d%p%d%d%d%d"), input:find ("%d%d%p%d%d%p%d%d%d%d") + 1))
		temp2 = tonumber(string.sub(input, input:find ("%d%d%p%d%d%p%d%d%d%d") + 3, input:find ("%d%d%p%d%d%p%d%d%d%d") + 4))
	end	
	if input:find ("%d%d%d%d%p%d%d%p%d%d") then
		temp1 = tonumber(string.sub(input, input:find ("%d%d%d%d%p%d%d%p%d%d") + 5, input:find ("%d%d%d%d%p%d%d%p%d%d") + 6))
		temp2 = tonumber(string.sub(input, input:find ("%d%d%d%d%p%d%d%p%d%d") + 8, input:find ("%d%d%d%d%p%d%d%p%d%d") + 9))
	end	
	if temp1 < 13 and temp2 > 12 then
		month = temp1
		xdate = temp2
	end
	if temp1 > 12 and temp2 < 13 then
		month = temp2
		xdate = temp1
	end
	if temp1 > 31 and temp2 > 31 then
		valid = 0
	end
	if temp1 < 13 and temp2 < 13 then
		month = temp2
		xdate = temp1
	end
end
function p.Monthss ()
	Months = {
			  "January",
			  "February",
			  "March",
			  "April",
			  "May",
			  "June",
			  "July",
			  "August",
			  "September",
			  "October",
			  "November",
			  "December"
	   	     }
	for i = 1, 12 do
		if input:find (Months[i]) then
			month = i
			hasMonth = 1
		end
	end
end
function p.Date ()
	if input:find ("%s%d%a%a%s") or input:find ("%s%d%d%a%a%s") then 
		if input:find ("%s%d%a%a%s") then
			xdate = tonumber(string.sub(input, input:find ("%s%d%a%a%s") + 1, input:find ("%s%d%a%a%s") + 1)) 
		end
		if input:find ("%s%d%d%a%a%s") then
			xdate = tonumber(string.sub(input, input:find ("%s%d%d%a%a%s") + 1, input:find ("%s%d%d%a%a%s") + 2)) 
		end
	else
		if input:find ("%s%d%d%s") or input:find ("%s%d%d%p") then
			if input:find ("%s%d%d%s") and input:find ("%s%d%d%p") then
				if input:find ("%s%d%d%s") < input:find ("%s%d%d%p") then
					xdate = tonumber(string.sub(input, input:find ("%s%d%d%s") + 1, input:find ("%s%d%d%s") + 2))
				else
					xdate = tonumber(string.sub(input, input:find ("%s%d%d%p") + 1, input:find ("%s%d%d%p") + 2))
				end
			else
				if input:find ("%s%d%d%s") then 
					xdate = tonumber(string.sub(input, input:find ("%s%d%d%s") + 1, input:find ("%s%d%d%s") + 2))
				else
					xdate = tonumber(string.sub(input, input:find ("%s%d%d%p") + 1, input:find ("%s%d%d%p") + 2))
				end
			end
			if xdate > 31 then valid = 0 end
			if xdate then hasDate = 1 end
		end
	end
end	
function p.leapYear ()
	if year % 100 ~= 0 and year % 4 == 0 then
		ly = 1
	else
		if year % 400 == 0 then
			ly = 1
		end
	end
end
function p.validation ()
	if hasYear == 0 and hasMonth == 0 then valid = 0 end
	if month > 12 then valid = 0 end
	if month == 4 then 
		if xdate > 30 then
			valid = 0
		end
	end
	if month == 6 then 
		if xdate > 30 then
			valid = 0
		end
	end
	if month == 9 then 
		if xdate > 30 then
			valid = 0
		end
	end
	if month == 11 then 
		if xdate > 30 then
			valid = 0
		end
	end
	if month == 2 then 
		if ly == 1 then 
			if xdate > 29 then
				valid = 0
			end
		else
			if xdate > 28 then
				valid = 0
			end
		end
	end
	if xdate then hasDate = 1 else hasDate = 0 end
end
function p.formats ()
	Months = {
			  "January",
			  "February",
			  "March",
			  "April",
			  "May",
			  "June",
			  "July",
			  "August",
			  "September",
			  "October",
			  "November",
			  "December"
	   	     }
	if xformat == "dmy" then
			if hasDate ~= 0 then 
				txt = txt .. xdate .. " " 
			end
			if hasMonth ~= 0 then
				txt = txt .. Months[month] .. " "
			end
			if hasYear ~= 0 then
				txt = txt .. year 
			end
	end
	if xformat == "mdy" then
		if month ~= 0 then
			txt = txt .. Months[month] .. " "
		end
		if xdate ~= 0 then 
			txt = txt .. xdate 
		end
		if year ~= 0 then
			txt = txt .. ", " .. year 
		end
	end
	if xformat == "iso" then
		txt = txt .. year  
		if month < 10 then 
			month = "0" .. month
			txt = txt .. "-" .. month 
		else
			txt =  txt .. "-" .. month 
		end
		if xdate < 10 then 
			xdate = "0" .. xdate
			txt = txt .. "-" .. xdate
		else
			txt = txt .. "-" .. xdate
		end
	end
	if xformat == "year" then
		if hasYear then
			txt = txt .. year .. " "
		else
			txt = "More information required. "
		end
	end
end
function p.suffixes ()
	if xsuffix == "AD" then
		txt = year .. " AD "
	end
	if xsuffix == "BC" then
		txt = "BC " .. year .. " "
	end
	if xsuffix == "CE" then
		txt = year .. " CE "
	end
	if xsuffix == "BCE" then
		txt = year .. " BCE "
	end
	if specialSuffix == 1 then
		txt = "c. " .. txt
	end
end
function p.sSuffixes ()
	if specialSuffix == 2 then
		txt = txt .. " (uncertain who was present)"
	end
	if specialSuffix == 3 then
		txt = "" .. year .. " AD"
	end
end
return p