-- Task 7 for Google Code-in | Date formatting)testList = possiblePatterns =
local allowedFormats =
-- First object in the array is prefix, second is a suffxlocal circa = local eraSuffix =
local monthsDays = local monthsNames = -- local months =
local p =
isLeapYear = function (yearRaw) year = tonumber(yearRaw) return (((year % 4
0))end
extractData = function (dateRaw) msg = "" matched = false -- print ('-- ' .. dateRaw .. ' --') for key, value in pairs(possiblePatterns) do if matched ~= true then local date = date.circa = false --
local match = match.match1, match.match2, match.match3 = dateRaw:match(value.pattern)
for ci, ciValue in pairs(circa) do for cmi,cmiValue in pairs(ciValue) do if ci
string.lower(cmiValue) then date.circa = true end end else local patternDropped = value.pattern:gsub("%)", ""):gsub("%(", "") local patternFinal = patternDropped .. " (" .. cmiValue .. ")" local circaPossibleMatch = dateRaw:match(patternFinal) if circaPossibleMatch ~= nil then if string.lower(circaPossibleMatch)
for ei=1,2 do -- suffix or preffix local era = eraSuffix[ei] for emi, emiPattern in pairs(eraSuffix[ei]) do local patternDropped = value.pattern:gsub("%)", ""):gsub("%(", "") local patternFinal = patternDropped .. " (" .. emiPattern .. ")" local circaPossibleMatch = dateRaw:match(patternFinal) if circaPossibleMatch ~= nil then if string.lower(circaPossibleMatch)
for i=1,string.len(value.format) + 1 do date[string.sub(value.format, i, i)] = match["match" .. i] end
if tonumber(date.y) ~= nil then date.y = tonumber(date.y) matched = true end
if date.m ~= nil and date.m ~= "" then matched = false local month = if tonumber(date.m) ~= nil then if (tonumber(date.m) or 13) <= 12 then month.name = monthsNames[tonumber(date.m)] month.length = monthsDays[tonumber(date.m)] month.id = tonumber(date.m) matched = true else if value.format
monthPrefixPossible then -- print(monthPrefix, monthPrefixPossible) month.name = monthsNames[mi] month.length = monthsDays[mi] month.id = mi matched = true end end else date.m = nil end
if month.name ~= nil and month.length ~= nil then matched = true date.m = month if date.d ~= nil and date.d ~= "" then matched = false date.d = tonumber(date.d) if date.m.length
true and date.d <= 29 then matched = true else -- print('INVALID ENTRY\n\n') matched = true return "Invalid entry" end elseif not (date.d <= month.length) then date.d = nil else matched = true end end end end if matched
formatDate = function (date, formatRaw) if (date
'Invalid entry') then return 'Invalid entry' elseif formatRaw ~= nil then local format = allowedFormats[formatRaw] or 'invalidFormat' if format
local finalFormat = format local formatIterator = format:gsub("%$", "") for l=1,#formatIterator do local char = formatIterator:sub(l,l) -- Day if char
nil then if formatRaw
"D" then if date.d
"iso" then return "Invalid entry" end finalFormat = finalFormat:gsub("%$D%$", "") else finalFormat = finalFormat:gsub("%$D%$", date.d) end end -- Year if char
nil then finalFormat = finalFormat:gsub("%$y%$", "") else finalFormat = finalFormat:gsub("%$y%$", date.y) end elseif char
nil then if formatRaw
"E" then if date.era
"iso" then return "Invalid entry" end finalFormat = finalFormat:gsub("%$E%$", "") else finalFormat = finalFormat:gsub("%$E%$", date.era) end end -- Month if char
nil then if formatRaw
"M" then if date.m
"iso" then return "Invalid entry" end finalFormat = finalFormat:gsub("%$M%$", "") else finalFormat = finalFormat:gsub("%$M%$", date.m.name) end end end -- Circa if date.circa then if formatRaw
if date.era and formatRaw
finalFormat = finalFormat:gsub("^%s*(.-)%s*$", "%1") finalFormat = finalFormat:gsub("%s+", " ") return finalFormat else local returnValue = "" if date.d then returnValue = returnValue .. date.d .. " " end if date.m then returnValue = returnValue .. date.m.name .. " " end if date.y then returnValue = returnValue .. date.y .. " " end if date.circa then returnValue = "circa " .. returnValue end if date.era then returnValue = returnValue .. date.era .. " " end return returnValue endend
p.convertTest = function (frame) local msg = "" for i=1, #testList do local testDate = testList[i] msg = msg .. "
p.convertDate = function (frame) local date = frame.args.date local format = frame.args.format if date
"" then return "Invalid entry" end return formatDate(extractData(date), format)end
return p