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 1: Line 1:


local p = {}
local p = {}
--[[--------------------------< F O R W A R D  D E C L A R A T I O N S >--------------------------------------
]]
local is_set, in_array; -- imported function from selected Module:Citation/CS1/Utilities


--[[--------------------------< I S _ V A L I D _ A C C E S S D A T E >----------------------------------------
--[[--------------------------< I S _ V A L I D _ A C C E S S D A T E >----------------------------------------
Line 103: Line 110:


]]
]]
 
local year_limit;
local function is_valid_year(year)
local function is_valid_year(year)
if not is_set(year_limit) then
if not is_set(year_limit) then
Line 263: Line 270:
if input.year ~= input.year2 then -- season year – season year range or season year–year
if input.year ~= input.year2 then -- season year – season year range or season year–year
tCOinS_date.rftssn = season[input.month]; -- start of range season; keep this?
tCOinS_date.rftssn = season[input.month]; -- start of range season; keep this?
if 0~= month2 then
if 0~= input.month2 then
tCOinS_date.rftchron = string.format ('%s %s – %s %s', season[input.month], input.year, season[input.month2], input.year2);
tCOinS_date.rftchron = string.format ('%s %s – %s %s', season[input.month], input.year, season[input.month2], input.year2);
end
end
Line 333: Line 340:
if date_string:match("^%d%d%d%d%-%d%d%-%d%d$") then -- year-initial numerical year month day format
if date_string:match("^%d%d%d%d%-%d%d%-%d%d$") then -- year-initial numerical year month day format
year, month, day=string.match(date_string, "(%d%d%d%d)%-(%d%d)%-(%d%d)");
year, month, day=string.match(date_string, "(%d%d%d%d)%-(%d%d)%-(%d%d)");
if 12 < tonumber(month) or 1 > tonumber(month) or 1583 > tonumber(year) then return false; end -- month number not valid or not Gregorian calendar
if 12 < tonumber(month) or 1 > tonumber(month) or 1582 > tonumber(year) or 0 == tonumber(day) then return false; end -- month or day number not valid or not Gregorian calendar
anchor_year = year;
anchor_year = year;


Line 571: Line 578:
year = year_string:match ('(%d%d%d%d?)');
year = year_string:match ('(%d%d%d%d?)');


if date_string:match ('%d%d%d%d%-%d%d%-%d%d') and year_string:match ('%d%d%d%d%a') then --special case where date and year required YYYY-MM-DD and YYYYx
if date_string:match ('%d%d%d%d%-%d%d%-%d%d') and year_string:match ('%d%d%d%d%a') then --special case where both date and year are required YYYY-MM-DD and YYYYx
date1 = date_string:match ('(%d%d%d%d)');
date1 = date_string:match ('(%d%d%d%d)');
year = year_string:match ('(%d%d%d%d)');
year = year_string:match ('(%d%d%d%d)');
Line 580: Line 587:
end
end
elseif date_string:match ("%d%d%d%d?.-%d%d%d%d?") then -- any of the standard formats of date with two three- or four-digit years
elseif date_string:match ("%d%d%d%d?.-%d%d%d%d?") then -- any of the standard range formats of date with two three- or four-digit years
date1, date2 = date_string:match ("(%d%d%d%d?).-(%d%d%d%d?)");
date1, date2 = date_string:match ("(%d%d%d%d?).-(%d%d%d%d?)");
if year ~= date1 and year ~= date2 then
if year ~= date1 and year ~= date2 then
Line 586: Line 593:
end
end


elseif date_string:match ("%d%d%d%d[%s%-–]+%d%d") then -- YYYY-YY date ranges
elseif date_string:match ("%d%d%d%d–%d%d") then -- YYYY-YY date ranges
local century;
local century;
date1, century, date2 = date_string:match ("((%d%d)%d%d)[%s%-–]+(%d%d)");
date1, century, date2 = date_string:match ("((%d%d)%d%d)[%s%-–]+(%d%d)");
Line 599: Line 606:
result = 0;
result = 0;
end
end
else
result = 0; -- no recognizable year in date
end
end
return result;
return result;
end
end


return {dates = dates, year_date_check = year_date_check} -- return exported functions
 
--[[-------------------------< R E F O R M A T  T A B L E S >------------------------------------------------
 
These table are used exclusively for reformatting dates
 
]]
 
local source_patterns = { -- this table holds patterns that match allowed date formats used to extract date components
['dmy'] = '(%d%d?)%s+(%a+)%s+(%d%d%d%d)',
['mdy'] = '(%a+)%s+(%d%d?),%s+(%d%d%d%d)',
['ymd'] = '(%d%d%d%d)%-(%d%d)-(%d%d)',
}
 
local short_formats = { -- this table holds format strings used by os.date() for short month names
['dmy'] = '%e %b %Y',
['mdy'] = '%b %e, %Y',
['ymd'] = '%F',
}
 
local long_formats = { -- this table holds format strings used by os.date() for long month names
['dmy'] = '%e %B %Y',
['mdy'] = '%B %e, %Y',
['ymd'] = '%F',
}
 
 
--[[-------------------------< G E T _ D M Y _ D A T E _ P A R T S >------------------------------------------
 
extracts year, month and day from DMY formatted date, places them in the source_date table, and returns.
 
]]
 
local function get_dmy_date_parts (date, source_date)
source_date.day, source_date.month, source_date.year = date:match (source_patterns['dmy']); -- get date components as strings
source_date.month = get_month_number (source_date.month); -- get month number
end
 
 
--[[-------------------------< G E T _ M D Y _ D A T E _ P A R T S >------------------------------------------
 
extracts year, month and day from MDY formatted date, places them in the source_date table, and returns.
 
]]
 
local function get_mdy_date_parts (date, source_date)
source_date.month, source_date.day, source_date.year = date:match (source_patterns['mdy']); -- get date components as strings
source_date.month = get_month_number (source_date.month); -- get month number
end
 
 
--[[-------------------------< G E T _ Y M D _ D A T E _ P A R T S >------------------------------------------
 
extracts year, month and day from YMD formatted date, places them in the source_date table, and returns.
 
]]
 
local function get_ymd_date_parts (date, source_date)
source_date.year, source_date.month, source_date.day = date:match (source_patterns['ymd']); -- get date components as strings
end
 
 
--[[-------------------------< R E F O R M A T _ D A T E S >--------------------------------------------------
 
Reformats existing dates into the format specified by format and short.
 
format is one of several keywords: dmy, dmy-all, mdy, mdy-all, ymd, ymd-all.  The all version includes access- and
archive-dates; otherwise these dates are not reformatted
 
Date ranges, season dates, proper name dates are not currently supported.
 
]]
 
local function reformat_dates (date_parameters_list, format, short)
local all = false; -- set to false to skip access- and archive-dates
local format_str;
local source_date = {};
if format:match('%a+%-all') then
format = format:match('(%a+)%-all'); -- extract the format
all = true; -- set to true to format access- and archive-dates
end
for param_name, param_val in pairs(date_parameters_list) do -- for each date-holding parameter in the list
if is_set(param_val) then -- if the parameter has a value
if not all and in_array (param_name, {'access-date', 'archive-date'}) then -- if access- or archive-date and format not xxx-all
param_val = ''; -- set to empty string so we don't process this date
end
for source, pattern in pairs(source_patterns) do
if param_val:match(pattern) then
if 'ymd' == source then
get_ymd_date_parts (param_val, source_date); -- get the date parts into the source_date table
elseif 'dmy' == source then
get_dmy_date_parts (param_val, source_date); -- get the date parts into the source_date table
elseif 'mdy' == source then
get_mdy_date_parts (param_val, source_date); -- get the date parts into the source_date table
end
 
if 'ymd' == format and 1582 > tonumber(source_date.year) then -- ymd format dates not allowed before 1582
return false; -- abandon reformatting
end
if short then
format_str = short_formats[format];
else
format_str = long_formats[format];
end
date_parameters_list[param_name] = os.date (format_str, os.time(source_date)); -- convert date and save
end
end
end
end
return true; -- declare success and done
end
 
 
--[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
 
Sets local imported functions table to same (live or sandbox) as that used by the other modules.
 
]]
 
local function set_selected_modules (utilities_page_ptr)
is_set = utilities_page_ptr.is_set; -- import functions from select Module:Citation/CS1/Utilities module
in_array = utilities_page_ptr.in_array; -- import functions from select Module:Citation/CS1/Utilities module
end
 
 
 
return { -- return exported functions
dates = dates,
year_date_check = year_date_check,
reformat_dates = reformat_dates,
set_selected_modules = set_selected_modules
}
Anonymous user