-- Task 9 of GCI 2019local p =
-- Main functionfunction p.formatDates(frame) local inputDate = tostring(frame.args.name) local inputFormat=tostring(frame.args.format) local inputTable = p.divideString(inputDate) local str="" local myDate = p.getDate(inputTable) local dateResults = p.checkDate(myDate) if(not(dateResults.isDateCorrect))then return dateResults.errorMessage else local outputFormat=p.chooseFormat(myDate, inputFormat) local completeMonths= if(myDate.isAprox)then str="circa " end if(outputFormat
"mdy")then str = str .. completeMonths[myDate.month] .. " " .. myDate.day .. ", " .. myDate.year elseif(outputFormat
"y")then str=str..myDate.year elseif(outputFormat
-- Selects correct output format.-- Returns a Stringfunction p.chooseFormat(dateObject, prefference) local correctFormat="" if(dateObject.dateFormat~= nil)then correctFormat=dateObject.dateFormat else correctFormat="#error" end local compatibleFormats = for n, actualFormat in ipairs(compatibleFormats) do if (prefference:lower
-- Truncates the input by spaces.-- Returns a tablefunction p.divideString(stringSentence) local nameTable = stringSentence = string.gsub(stringSentence, "-", " ") stringSentence = string.gsub(stringSentence, "/", " ") for m in string.gmatch(stringSentence, ("%S+")) do table.insert(nameTable, m) end return nameTableend
-- Detects input date.-- Returns a Objectfunction p.getDate(stringTable) local comparison = "" local finalDate = local dateIsStored = false -- Matchs string month with correspoding number. -- Returns number function getMonth(strInput) local months = if(strInput:find("(%a+)"))then for w, month in ipairs(months)do if(strInput:lower:find(month)~= nil)then return tonumber(w) end end end return 0 end -- Match given ordinal number to its cardinal value. -- Returns a number function getCardinal(inputStr) if(inputStr:find("(%d+)(%a+)"))then local number, termination=inputStr:lower:match("(%d+)(%a+)") suffixes = for g, suffix in ipairs(suffixes)do if(termination:find(suffix))then return tonumber(number) end end end return 0 end -- Start comparison for z, number in ipairs(stringTable) do -- Creates a string of three followed items. if(z<=#stringTable-2)then local comparison = stringTable[z] .. " " .. stringTable[z+1] .. " " .. stringTable[z+2] -- Search for the format 'typedMonth Day, Year'. if(comparison:lower:find("(%a+) (%d+), (%d+)"))then local m, d, y = comparison:lower:match("(%a+) (%d+), (%d+)") finalDate.month=tonumber(getMonth(m)) finalDate.year=tonumber(y) finalDate.day=tonumber(d) finalDate.dateFormat="mdy" dateIsStored=true end -- Search for the format 'Day typedMonth Year' if(comparison:lower:find("(%d+) (%a+) (%d+)") and not(dateIsStored))then local d, m, y = comparison:lower:match("(%d+) (%a+) (%d+)") finalDate.month=getMonth(m:lower) finalDate.year=tonumber(y) finalDate.day=tonumber(d) finalDate.dateFormat="dmy" if(finalDate.month
0)then dateIsStored=false else dateIsStored=true end end -- Search for format 'ordinalDay typedMonth Year' if(comparison:lower:find("(%w+) (%a+) (%d+)") and not(dateIsStored))then local d, m, y=comparison:lower:match("(%w+) (%a+) (%d+)") finalDate.day=getCardinal(d) finalDate.month=getMonth(m) finalDate.year=y -- This format isn't allowed. The most similar is ISO. finalDate.dateFormat="iso" if(finalDate.month
number:lower)then finalDate.specifiedEra=specific:upper end end end end if(not(dateIsStored))then for k, number in ipairs(stringTable) do -- Creates a string of two followed elements. if(k<=#stringTable-1)then local comparison = stringTable[k] .. " " .. stringTable[k+1] -- Search for a date in format 'Day typedMonth' if(comparison:lower:find("(%d+) (%a+)"))then local d, m=comparison:lower:match("(%d+) (%a+)") finalDate.day=tonumber(d) finalDate.month=tonumber(getMonth(m)) -- This format isn't allowed. The most similar is ISO. finalDate.dateFormat="iso" if(finalDate.month
0)then dateIsStored=false else dateIsStored=true end end -- Search for a date in format 'typedMonth Year' if(comparison:lower:find("(%a+) (%d+)"))then local m, y=comparison:lower:match("(%a+) (%d+)") finalDate.month=getMonth(m) finalDate.year=tonumber(y) finalDate.dateFormat="my" if(finalDate.month
0 and number:find("(%d+)"))then -- Search for ordinal day finalDate.day=getCardinal(number) if(not(finalDate.day
0)then -- Search for months finalDate.month=tonumber(getMonth(number)) if(not(finalDate.month
1 and #stringTable
2 and #stringTable
-- Checks that given date-- Returns a objectfunction p.checkDate(givenDate) -- Detects is the given year is leap. -- Returns a boolean function isLeap(yearInput) local yearIsLeap = (tonumber(yearInput)%4)
0)then yearIsLeap = (tonumber(yearInput)%400)
nil))then if(givenDate.day>31)then finalObject.isDateCorrect=false finalObject.errorMessage="That day doesn't exists!" return finalObject end end if(not(givenDate.month
2)then if(isLeap(givenDate.year))then if(givenDate.day>29)then finalObject.isDateCorrect=false finalObject.errorMessage="That day doesn't exists!" end else if(givenDate.day>=29)then finalObject.isDateCorrect=false finalObject.errorMessage="That day doesn't exists!" end end end end -- Check if month is correct if(not(givenDate.month
0 and givenDate.day
0)then finalObject.isDateCorrect=false finalObject.errorMessage="No date was detected." end return finalObjectendreturn p