Home
Random
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:Sandbox/Takidelfin/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 7 for Google Code-in | Date formatting) testList = { "31 august 2013", "31 August 2013", "31 August 2013 (uncertain)", "August 27, 2013", "29 February 2004 (uncertain)", "29 February 2005 (uncertain)", "27/08/2013", "04/27/2013", "2013-08-27", "2013 (uncertain)", "27", "27 December", "27 2017", "sometime around 27th August 2013", "on the 16th of December in the year of our Lord 1770", "on the 16th of December in the year skjdgfgjksdgjkheg hgj32g gh 11 of our Lord 1770", "99 red balloons", "sometime around 3rd August 2013", "31 August 103 AD", "31 August 2013 BC", "31 August 2013 BCE", "31 August 103 CE", "31 August 13 BC", "31 August 13", "31 August 213", "213", "30 BCE", "3 may 2017", "3 Jan 2017", "31 February 2013", "the quick brown fox", "4 and 20 blackbirds ...", "3 jan 9 AD" } possiblePatterns = { { pattern = "(%d+) (%w+) (%d+)", format = "dmy" }, { pattern = "(%d+)st (%w+), (%d+)", format = "dmy" }, { pattern = "(%d+)nd (%w+), (%d+)", format = "dmy" }, { pattern = "(%d+)rd (%w+), (%d+)", format = "dmy" }, { pattern = "(%d+)th (%w+), (%d+)", format = "dmy" }, { pattern = "(%d+)st (%w+) (%d+)", format = "dmy" }, { pattern = "(%d+)nd (%w+) (%d+)", format = "dmy" }, { pattern = "(%d+)rd (%w+) (%d+)", format = "dmy" }, { pattern = "(%d+)th (%w+) (%d+)", format = "dmy" }, { pattern = "(%d+)th of (%w+) .+ (%d+)", format = "dmy" }, { pattern = "(%w+) (%d+)th (%d+)", format = "mdy" }, { pattern = "(%w+) (%d+), (%d+)", format = "mdy" }, { pattern = "(%d+)/(%d+)/(%d+)", format = "dmy" }, { pattern = "(%d+)/(%d+)/(%d+)", format = "mdy" }, { pattern = "(%d+)/(%d+)", format = "my" }, { pattern = "(%d+)-(%d+)-(%d+)", format = "ymd" }, { pattern = "(%d+) (%w+)", format = "ym" }, { pattern = "(%d%d%d%d%d)", format = "y" }, { pattern = "(%d%d%d%d)", format = "y" }, { pattern = "(%d%d%d)", format = "y" }, { pattern = "year (%d+)", format = "y" }, { pattern = "(%d+)", format = "y" } } local allowedFormats = { ["dmy"] = "$D$ $M$ $y$ $E$", ["mdy"] = "$M$ $D$ $y$ $E$", ["iso"] = "$Y$-$m$-$d$", ["year"] = "$y$ $E$", ["y"] = "$y$ $E$", ["my"] = "$M$ $y$ $E$" } -- First object in the array is prefix, second is a suffx local circa = { { "sometime around", "around" }, { "%(uncertain%)" } } local eraSuffix = { { "AD", "CE" }, -- { "BC", "BCE" } } local monthsDays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } local monthsNames = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" } -- local months = { ["January"] = 31, ["February"] = 28, ["March"] = 31, ["April"] = 30, ["May"] = 31, ["June"] = 30, ["July"] = 31, ["August"] = 31, ["September"]= 30, ["October"]= 31, ["November"] = 30, ["December"] = 31 } local p = {} isLeapYear = function ( yearRaw ) year = tonumber(yearRaw) return (((year % 4 == 0) and (year % 100 ~= 0)) or (year % 400 == 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 --[[ Expected date look: date.y = Integer date.m = Object, { length = Integer, <= 31 id = Integer, <= 12 name = String, vaild month name starting with capital letter } date.d = Integer, <= date.m.length date.era = String, vaild era shorthand date.circa = boolean ]] 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 == 1 then local patternDropped = value.pattern:gsub( "%)", "" ):gsub( "%(", "" ) local patternFinal = "(" .. cmiValue .. ") " .. patternDropped local circaPossibleMatch = dateRaw:match( patternFinal ) -- print(patternFinal) if circaPossibleMatch ~= nil then if string.lower( circaPossibleMatch ) == 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 ) == string.lower( cmiValue:gsub("%%%(", "("):gsub("%%%)", ")") ) then date.circa = true end end end end -- match.circa = dateRaw:match( "%d+ (AB)" ) end 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 ) == string.lower( emiPattern ) then date.era = emiPattern end end end end -- Each value.pattern (pattern) has got an value.format (date format) associated with it -- this loops iterates thorough them and assings variables to proper value.formats 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 == 'mdy' then -- print('INVALID ENTRY\n\n') return "Invalid entry" end end elseif #date.m > 1 then for mi=1,#monthsNames do local monthPrefixPossible = string.upper( string.sub( monthsNames[mi], 1, 3 ) ) local monthPrefix = string.upper( string.sub( date.m, 1, 3 ) ) if monthPrefix == 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 == 29 and date.y ~= nil then if isLeapYear(date.y) == 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 == true then -- local dateMsg = "" -- if date.y then -- dateMsg = dateMsg .. date.y -- end -- if date.m then -- dateMsg = dateMsg .. " " .. date.m.name -- end -- if date.d then -- dateMsg = dateMsg .. " " .. date.d -- end -- if date.circa then -- dateMsg = "circa " .. dateMsg -- end -- if date.era then -- dateMsg = dateMsg .. " " .. date.era -- end -- print( 'FORMAT: ' .. value.format ) -- print( 'PATTERN: ' .. value.pattern ) -- print( 'CIRCA: ' .. tostring(date.circa) ) -- print( 'ERA: ' .. tostring(date.era) ) -- print( '--- Result ---' ) -- print(dateMsg) -- print('\n\n') return date end end end end formatDate = function ( date, formatRaw ) if (date == nil) or (date == 'Invalid entry') then return 'Invalid entry' elseif formatRaw ~= nil then local format = allowedFormats[formatRaw] or 'invalidFormat' if format == 'invalidFormat' then 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 end local finalFormat = format local formatIterator = format:gsub("%$", "") for l=1,#formatIterator do local char = formatIterator:sub(l,l) -- Day if char == "d" then if date.d == nil then if formatRaw == "iso" then return "Invalid entry" end finalFormat = finalFormat:gsub("%$d%$", "") elseif #tostring(date.d) < 2 then finalFormat = finalFormat:gsub("%$d%$", 0 .. date.d) else finalFormat = finalFormat:gsub("%$d%$", date.d) end elseif char == "D" then if date.d == nil then if formatRaw == "iso" then return "Invalid entry" end finalFormat = finalFormat:gsub("%$D%$", "") else finalFormat = finalFormat:gsub("%$D%$", date.d) end end -- Year if char == "y" then if date.y == nil then finalFormat = finalFormat:gsub("%$y%$", "") else finalFormat = finalFormat:gsub("%$y%$", date.y) end elseif char == "Y" then if date.y == nil then if formatRaw == "iso" then return "Invalid entry" end finalFormat = finalFormat:gsub("%$Y%$", "") elseif 0 <= date.y and date.y <= 9999 then local zero = "0" finalFormat = finalFormat:gsub("%$Y%$", zero:rep(4 - #tostring(date.y)) .. date.y) else return "Invalid entry" end end -- Era if char == "E" then if date.era == nil then if formatRaw == "iso" then return "Invalid entry" end finalFormat = finalFormat:gsub("%$E%$", "") else finalFormat = finalFormat:gsub("%$E%$", date.era) end end -- Month if char == "m" then if date.m == nil then if formatRaw == "iso" then return "Invalid entry" end finalFormat = finalFormat:gsub("%$m%$", "") else local zero = "0" finalFormat = finalFormat:gsub("%$m%$", zero:rep(2 - #tostring(date.m.id)) .. date.m.id) end elseif char == "M" then if date.m == nil then if formatRaw == "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 == "iso" then return "ISO format does not allow uncertain dates" end finalFormat = "circa " .. finalFormat end if date.era and formatRaw == "iso" then return "ISO format does not allow embedding era into date" end 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 end end p.convertTest = function ( frame ) local msg = "" for i=1, #testList do local testDate = testList[i] msg = msg .. "<br/> <ul>Raw date: " .. testDate for key,value in pairs(allowedFormats) do msg = msg .. "<li> <b>Format:</b> " .. key .. " | <b>Result:</b> " .. formatDate( extractData( testDate ), key ) .. "</li>" end msg = msg .. "</ul>" end return msg end p.convertDate = function ( frame ) local date = frame.args.date local format = frame.args.format if date == nil or date == "" then return "Invalid entry" end return formatDate( extractData( date ), format ) 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/Takidelfin/Dates/doc
(
edit
)