Open main menu
Home
Random
Donate
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:Sandbox/Ajuanca/Dates
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
-- Task 9 of GCI 2019 local p = {} -- Main function function 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={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} if(myDate.isAprox)then str="circa " end if(outputFormat=="dmy")then str = str .. myDate.day .. " " .. completeMonths[myDate.month] .. " " .. myDate.year elseif(outputFormat=="mdy")then str = str .. completeMonths[myDate.month] .. " " .. myDate.day .. ", " .. myDate.year elseif(outputFormat=="iso")then str = str .. myDate.year .. "-" .. myDate.month .. "-" .. myDate.day elseif(outputFormat=="y")then str=str..myDate.year elseif(outputFormat=="my")then str=str.. completeMonths[myDate.month] .. " " .. myDate.year end if(myDate.specifiedEra~= nil)then str = str .." "..myDate.specifiedEra end end return str end -- Selects correct output format. -- Returns a String function p.chooseFormat(dateObject, prefference) local correctFormat="" if(dateObject.dateFormat~= nil)then correctFormat=dateObject.dateFormat else correctFormat="#error" end local compatibleFormats = {"dmy", "mdy", "iso", "y", "my"} for n, actualFormat in ipairs(compatibleFormats) do if (prefference:lower() == actualFormat) then correctFormat=prefference:lower() break end end return correctFormat end -- Truncates the input by spaces. -- Returns a table function 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 nameTable end -- Detects input date. -- Returns a Object function p.getDate(stringTable) local comparison = "" local finalDate = { day = 0, month = 0, year = 0, isAprox=false, specifiedEra=nil, dateFormat=nil } local dateIsStored = false -- Matchs string month with correspoding number. -- Returns number function getMonth(strInput) local months = {"jan", "feb", "mar", "apr", "may", "june", "july", "aug", "sept", "oct", "nov", "dec"} 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 = {"st", "nd", "rd", "th"} 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 the format 'Day Month Year' or 'Year Month Day' if(comparison:lower():find("(%d+) (%d+) (%d+)") and not(dateIsStored))then local d, m, y= comparison:lower():match("(%d+) (%d+) (%d+)") -- If day and year are both less than 31, it'll be considered d-m-y if(tonumber(d)>31)then local temporalDay=y y=d d=temporalDay end finalDate.month=tonumber(m) finalDate.year=tonumber(y) finalDate.day=tonumber(d) -- 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 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==0)then dateIsStored=false else dateIsStored=true end end end -- Searchs for aproximations indicators local aproxIndicators = {"circa", "approx", "around", "uncertain"} for z, indicator in ipairs(aproxIndicators)do if(number:lower():match(indicator))then finalDate.isAprox=true end end -- Searchs for era indicators. Note that, althought it isn't used, -- the value g gives us the calendar used. local eraIndicators={{"bce", "bc"}, {"ce", "ad"}} for d, era in ipairs(eraIndicators)do for g, specific in ipairs(era)do if(specific==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 -- Search for a date in format 'ordinalDay typedMonth' elseif(comparison:lower():find("(%w+) (%a+)"))then local d, m=comparison:lower():match("(%w+) (%a+)") finalDate.day=getCardinal(d) finalDate.month=getMonth(m) -- This format isn't allowed. The most similar is ISO. finalDate.dateFormat="iso" if(finalDate.day==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)then dateIsStored=false else dateIsStored=true end end end end end -- Search for a result if nothing is still found. if(not(dateIsStored))then local numbersFound = {} for n, number in ipairs(stringTable)do -- Search for possible given values in an non-regulated order. if(number:find("(%a+)")~=nil)then if(finalDate.day==0 and number:find("(%d+)"))then -- Search for ordinal day finalDate.day=getCardinal(number) if(not(finalDate.day==0))then finalDate.dateFormat="dmy" end elseif(finalDate.month==0)then -- Search for months finalDate.month=tonumber(getMonth(number)) if(not(finalDate.month==0))then finalDate.dateFormat="my" end end else table.insert(numbersFound, tonumber(number)) end if(#numbersFound==1 and #stringTable==n)then finalDate.year=numbersFound[1] if((finalDate.month~=0) and (finalDate.day~=0))then finalDate.dateFormat="dmy" elseif(finalDate.month~=0)then finalDate.dateFormat="my" else finalDate.dateFormat="y" end elseif(#numbersFound==2 and #stringTable==n)then if(numbersFound[1]<=31) then finalDate.day=numbersFound[1] finalDate.year=numbersFound[2] else finalDate.year=numberFound[1] finalDate.day=numberFound[2] end finalDate.dateFormat="y" end end end return finalDate end -- Checks that given date -- Returns a object function p.checkDate(givenDate) -- Detects is the given year is leap. -- Returns a boolean function isLeap(yearInput) local yearIsLeap = (tonumber(yearInput)%4)==0 if((tonumber(yearInput)%100)==0 )then yearIsLeap = (tonumber(yearInput)%400)==0 end return yearIsLeap end local finalObject = { isDateCorrect=true, errorMessage="" } -- Check if day is correct if(not(givenDate.day==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==nil))then if(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==nil))then if(givenDate.month>12)then finalObject.isDateCorrect=false finalObject.errorMessage="That month doesn't exist!" end end -- Check if date is nil if(givenDate.year==0 and givenDate.day==0 and givenDate.month==0)then finalObject.isDateCorrect=false finalObject.errorMessage="No date was detected." end return finalObject end return p
Summary:
Please note that all contributions to Stockhub may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Stockhub:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Template used on this page:
Module:Sandbox/Ajuanca/Dates/doc
(
edit
)