Module:Citation/CS1/Date validation: Difference between revisions

Synch from sandbox;
m>Trappist the monk
(Synch from sandbox;)
m>Trappist the monk
(Synch from sandbox;)
Line 2: Line 2:
local p = {}
local p = {}


-- returns a number according to the month in a date: 1 for January, etc.  Capitalization and spelling must be correct. If not a valid month, returns 0
--[[--------------------------< I S _ V A L I D _ A C C E S S D A T E >----------------------------------------
 
returns true if:
Wikipedia start date <= accessdate < today + 2 days
 
Wikipedia start date is 2001-01-15T00:00:00 UTC which is 979516800 seconds after 1970-01-01T00:00:00 UTC (the start of Unix time)
accessdate is the date provided in |accessdate= at time 00:00:00 UTC
today is the current date at time 00:00:00 UTC plus 48 hours
if today is 2015-01-01T00:00:00 then
adding 24 hours gives 2015-01-02T00:00:00 – one second more than today
adding 24 hours gives 2015-01-03T00:00:00 – one second more than tomorrow
 
]]
 
local function is_valid_accessdate (accessdate)
local lang = mw.getContentLanguage();
local good1, good2;
local access_ts, tomorrow_ts; -- to hold unix time stamps representing the dates
good1, access_ts = pcall( lang.formatDate, lang, 'U', accessdate ); -- convert accessdate value to unix timesatmp
good2, tomorrow_ts = pcall( lang.formatDate, lang, 'U', 'today + 2 days' ); -- today midnight + 2 days is one second more than all day tomorrow
if good1 and good2 then
access_ts = tonumber (access_ts); -- convert to numbers for the comparison
tomorrow_ts = tonumber (tomorrow_ts);
else
return false; -- one or both failed to convert to unix time stamp
end
if 979516800 <= access_ts and access_ts < tomorrow_ts then -- Wikipedia start date <= accessdate < tomorrow's date
return true;
else
return false; -- accessdate out of range
end
end
 
--[[--------------------------< G E T _ M O N T H _ N U M B E R >----------------------------------------------
 
returns a number according to the month in a date: 1 for January, etc.  Capitalization and spelling must be correct. If not a valid month, returns 0
 
]]
 
local function get_month_number (month)
local function get_month_number (month)
local long_months = {['January']=1, ['February']=2, ['March']=3, ['April']=4, ['May']=5, ['June']=6, ['July']=7, ['August']=8, ['September']=9, ['October']=10, ['November']=11, ['December']=12};
local long_months = {['January']=1, ['February']=2, ['March']=3, ['April']=4, ['May']=5, ['June']=6, ['July']=7, ['August']=8, ['September']=9, ['October']=10, ['November']=11, ['December']=12};
Line 14: Line 55:
end
end


-- returns a number according to the sequence of seasons in a year: 1 for Winter, etc.  Capitalization and spelling must be correct. If not a valid season, returns 0
--[[--------------------------< G E T _ S E A S O N _ N U M B E R >--------------------------------------------
 
returns a number according to the sequence of seasons in a year: 1 for Winter, etc.  Capitalization and spelling must be correct. If not a valid season, returns 0
 
]]
 
local function get_season_number (season)
local function get_season_number (season)
local season_list = {['Winter']=1, ['Spring']=2, ['Summer']=3, ['Fall']=4, ['Autumn']=4}
local season_list = {['Winter']=1, ['Spring']=2, ['Summer']=3, ['Fall']=4, ['Autumn']=4}
Line 22: Line 68:
return 0; -- misspelled, improper case, or not a season name
return 0; -- misspelled, improper case, or not a season name
end
end
--[[--------------------------< I S _ P R O P E R _ N A M E >--------------------------------------------------
returns a non-zero number if date contains a recognized proper name.  Capitalization and spelling must be correct.
]]
local function is_proper_name (name)
local name_list = {['Christmas']=1}
local temp;
temp=name_list[name];
if temp then return temp; end -- if name is a valid name return its number
return 0; -- misspelled, improper case, or not a proper name
end
--[[--------------------------< I S _ V A L I D _ M O N T H _ O R _ S E A S O N >------------------------------


--returns true if month or season is valid (properly spelled, capitalized, abbreviated)
--returns true if month or season is valid (properly spelled, capitalized, abbreviated)
]]
local function is_valid_month_or_season (month_season)
local function is_valid_month_or_season (month_season)
if 0 == get_month_number (month_season) then -- if month text isn't one of the twelve months, might be a season
if 0 == get_month_number (month_season) then -- if month text isn't one of the twelve months, might be a season
Line 143: Line 208:
end
end


--[[
--[[--------------------------< C H E C K _ D A T E >----------------------------------------------------------
 
Check date format to see that it is one of the formats approved by WP:DATESNO or WP:DATERANGE. Exception: only allowed range separator is endash.
Check date format to see that it is one of the formats approved by WP:DATESNO or WP:DATERANGE. Exception: only allowed range separator is endash.
Additionally, check the date to see that it is a real date: no 31 in 30-day months; no 29 February when not a leap year.  Months, both long-form and three
Additionally, check the date to see that it is a real date: no 31 in 30-day months; no 29 February when not a leap year.  Months, both long-form and three
Line 254: Line 320:
end
end
elseif date_string:match("^%a+ +%d%d%d%d%a?$") then -- month/season year
elseif date_string:match("^%a+ +%d%d%d%d%a?$") then -- month/season year or proper-name year
month, anchor_year, year=date_string:match("(%a+)%s*((%d%d%d%d)%a?)");
month, anchor_year, year=date_string:match("(%a+)%s*((%d%d%d%d)%a?)");
if not is_valid_year(year) then return false; end
if not is_valid_year(year) then return false; end
if not is_valid_month_or_season (month) then return false; end
if not is_valid_month_or_season (month) and 0 == is_proper_name (month) then return false; end


elseif date_string:match("^[1-9]%d%d%d?–[1-9]%d%d%d?%a?$") then -- Year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999
elseif date_string:match("^[1-9]%d%d%d?–[1-9]%d%d%d?%a?$") then -- Year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999
Line 345: Line 411:
else
else
good_date, anchor_year, COinS_date = check_date (v); -- go test the date
good_date, anchor_year, COinS_date = check_date (v); -- go test the date
end
elseif 'accessdate'==k then -- if the parameter is |date=
good_date = check_date (v); -- go test the date
if true == good_date then -- if the date is a valid date
good_date = is_valid_accessdate (v); -- is Wikipedia start date < accessdate < tomorrow's date?
end
end
else -- any other date-holding parameter
else -- any other date-holding parameter
Anonymous user