Home
Random
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:Sandbox/dxa-kly/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!
local indef = {"about", "approaching", "approximate", "around", "%f[%a]c%.%f[%A]", "%f[%a]ca%f[%A]", "circa", "close to", "doubt", "dubious", "estimate", "in the area of", "in the neighborhood of", "in the neighbourhood of", "in the neighborhood of", "in the region of", "more or less", "near", "or so", "order of", "roughly", "something like", "speculative", "tentative", "uncertain", "unclear", "unreliable", "unsettled", "unsure"} local months = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"} local fullmonths = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} local eras = {"ad", "bce", "bc", "ce"} local bad = "Invalid entry" local p = {} function p.day_try( d, m, y ) if m == 1 or m == 3 or m == 5 or m == 7 or m == 8 or m == 10 or m == 12 then d_in_m = 31 elseif m == 4 or m == 6 or m == 9 or m == 11 then d_in_m = 30 elseif m == 2 then if y % 4 < 1 and y % 400 > 0 then d_in_m = 29 else d_in_m = 28 end else d_in_m = 0 end if d > 0 and d <= d_in_m then return 1 end end function p.era_try( str, ptn, idx ) for i = 1, #eras do values = {str:match(ptn .. " (" .. eras[i] .. ")")} for j = 1, #values do if j == idx then if idx > 2 and idx < 5 then return values[idx] elseif idx == 2 then return values[1], values[2] end end end end end function p.indef_try( str ) for i = 1, #indef do if str:match(indef[i]) then return true end end return false end function p.mth_str_to_int( m ) for i = 1, #months do if months[i] == m then return i end end end function p.slash_try( str ) sls_num1, sls_num2, sls_y = str:match("(%d+)/(%d+)/(%d+)") sls_num1 = tonumber(sls_num1) sls_num2 = tonumber(sls_num2) if sls_num1 then if sls_num2 > 12 then if not p.day_try(sls_num2, sls_num1, sls_y) then return bad end return "iso", sls_y, sls_num1, sls_num2 else if not p.day_try(sls_num1, sls_num2, sls_y) then return bad end return "iso", sls_y, sls_num2, sls_num1 end end end function p.hyphenated_try( str ) hyn_y, hyn_m, hyn_d = str:match("(%d+)-(%d+)-(%d+)") hyn_y = tonumber(hyn_y) hyn_m = tonumber(hyn_m) hyn_d = tonumber(hyn_d) if hyn_y then if not p.day_try(hyn_d, hyn_m, hyn_y) then return bad end return "iso", hyn_y, hyn_m, hyn_d end end function p.named_month_try( str ) for _, pattern in pairs( months ) do dmy_d, dmy_m, dmy_y = str:match( "(%d+).-(" .. pattern .. ").-(%d+)" ) mdy_m, mdy_d, mdy_y = str:match( "(" .. pattern .. ").-(%d+)[^%d]+(%d+)") if dmy_d then dmy_d = tonumber(dmy_d) dmy_m = p.mth_str_to_int(dmy_m) dmy_y = tonumber(dmy_y) if not p.day_try(tonumber(dmy_d), dmy_m, tonumber(dmy_y)) then return bad end era = p.era_try(str, "(%d+).-(" .. pattern .. ").-(%d+)", 4) if era then return "dmy", dmy_y, dmy_m, dmy_d, era else return "dmy", dmy_y, dmy_m, dmy_d end elseif mdy_m then mdy_m = p.mth_str_to_int(mdy_m) mdy_d = tonumber(mdy_d) mdy_y = tonumber(mdy_y) if not p.day_try(tonumber(mdy_d), mdy_m, tonumber(mdy_y)) then return bad end era = p.era_try(str, "(" .. pattern .. ").-(%d+)[^%d]+(%d+)", 4) if era then return "mdy", mdy_y, mdy_m, mdy_d, era else return "mdy", mdy_y, mdy_m, mdy_d end end end fail1_d, fail1_m, fail1_y = str:match( "(%d+).-(%a+).-(%d+)" ) fail2_m, fail2_d, fail2_y = str:match( "(%a+).-(%d+)[^%d]+(%d+)") if fail1_d or fail2_m then return bad end end function p.unclassified1_try( str, ptn ) un1_d, un1_m = str:match( "(%d+).-(" .. ptn .. ")" ) un1_d = tonumber(un1_d) un1_m = p.mth_str_to_int(un1_m) if un1_d and p.day_try(un1_d, un1_m, 1900) then return "dm", un1_d, fullmonths[un1_m] end end function p.unclassified2_try( str, ptn ) un2_m, un2_d = str:match( "(" .. ptn .. ").-(%d+)" ) un2_d = tonumber(un2_d) un2_m = p.mth_str_to_int(un2_m) if un2_d then era = p.era_try(str, "(" .. ptn .. ").-(%d+)", 3) if era then return "my", fullmonths[un2_m], un2_d, era elseif p.day_try(un2_d, un2_m, 1900) then return "md", fullmonths[un2_m], un2_d else return "my", fullmonths[un2_m], un2_d end end end function p.unclassified3_try( str ) un3_y, era = p.era_try(str, "(%d+)", 2) if era then return "ye", un3_y, era end end function p.unclassified4_try( str ) t = {} for a in str:gmatch("%d+") do table.insert(t, tonumber(a)) end table.sort(t) if not (t[#t] == nil) then return "num", t[#t] end end function p.parsedate( inp ) inp = inp or "" if not (type(inp) == "string") then return bad end inp = inp:lower() has_indef = p.indef_try(inp) if p.slash_try(inp) then return has_indef, p.slash_try(inp) elseif p.hyphenated_try(inp) then return has_indef, p.hyphenated_try(inp) elseif p.named_month_try(inp) then return has_indef, p.named_month_try(inp) else for _, pattern in pairs( months ) do if p.unclassified1_try( inp, pattern ) then return has_indef, p.unclassified1_try(inp, pattern) elseif p.unclassified2_try( inp, pattern ) then return has_indef, p.unclassified2_try(inp, pattern) end end if p.unclassified3_try(inp) then return has_indef, p.unclassified3_try(inp) elseif p.unclassified4_try(inp) then return has_indef, p.unclassified4_try(inp) end end return bad end function p.unpackdate( frame ) s = {p.parsedate(frame.args.text)} format = frame.args.format uncertainty = "" era = "" if s[1] then uncertainty = "circa " end for i = 1, #s do if s[i] == "Invalid entry" then return s[i] end end if s[2] == "iso" or s[2] == "dmy" or s[2] == "mdy" then year = s[3] month = s[4] day = s[5] if s[6] then era = s[6]:upper() end if s[2] == "iso" then default = string.format("%04d-%02d-%02d", year, month, day) elseif s[2] == "dmy" then default = day .. " " .. fullmonths[month] .. " " .. year .. " " .. era else default = fullmonths[month] .. " " .. day .. ", " .. year .. " " .. era end elseif s[2] == "dm" or s[2] == "md" then default = s[3] .. " " .. s[4] elseif s[2] == "ye" then default = s[3] .. " " .. s[4]:upper() elseif s[2] == "my" then default = s[3] .. " " .. s[4] if s[5] then default = default .. " " .. s[5]:upper() end else default = s[3] end if format then if s[2] == "iso" or s[2] == "dmy" or s[2] == "mdy" then if format == s[2] then return uncertainty .. default end if format == "iso" then return uncertainty .. string.format("%04d-%02d-%02d", year, month, day) end if format == "dmy" then return uncertainty .. day .. " " .. fullmonths[month] .. " " .. year .. " " .. era end if format == "mdy" then return uncertainty .. fullmonths[month] .. " " .. day .. ", " .. year .. " " .. era end if format == "year" then return uncertainty .. year .. " " .. era end end return "Cannot apply format" else return uncertainty .. default end 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/dxa-kly/Dates/doc
(
edit
)