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 | 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% | 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 | ||
--[[-------------------------< 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 | |||
} |