Module:Citation/CS1/Date validation: Difference between revisions
no edit summary
imported>Rob Kam m (1 revision imported) |
m>Trappist the monk No edit summary |
||
Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
Line 35: | Line 36: | ||
good2, tomorrow_ts = pcall( lang.formatDate, lang, 'U', 'today + 2 days' ); -- today midnight + 2 days is one second more than all day tomorrow | 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 | if good1 and good2 then -- lang.formatDate() returns a timestamp in the local script which which tonumber() may not understand | ||
access_ts = tonumber (access_ts); | access_ts = tonumber (access_ts) or lang:parseFormattedNumber (access_ts); -- convert to numbers for the comparison; | ||
tomorrow_ts = tonumber (tomorrow_ts); | tomorrow_ts = tonumber (tomorrow_ts) or lang:parseFormattedNumber (tomorrow_ts); | ||
else | else | ||
return false; -- one or both failed to convert to unix time stamp | return false; -- one or both failed to convert to unix time stamp | ||
Line 262: | Line 263: | ||
The input table has: | The input table has: | ||
year, year2 – always present; if before 1582, ignore months and days if present | year, year2 – always present; if before 1582, ignore months and days if present | ||
month, month2 – 0 if not provided, 1-12 for months, 21-24 for seasons; | month, month2 – 0 if not provided, 1-12 for months, 21-24 for seasons; 99 Christmas | ||
day, day2 – 0 if not provided, 1-31 for days | day, day2 – 0 if not provided, 1-31 for days | ||
Line 275: | Line 276: | ||
local date; -- one date or first date in a range | local date; -- one date or first date in a range | ||
local date2 = ''; -- end of range date | local date2 = ''; -- end of range date | ||
-- start temporary Julian / Gregorian calendar uncertainty detection | |||
local year = tonumber(input.year); -- this temporary code to determine the extent of sources dated to the Julian/Gregorian | |||
local month = tonumber(input.month); -- interstice 1 October 1582 – 1 January 1926 | |||
local day = tonumber (input.day); | |||
if (0 ~= day) and -- day must have a value for this to be a whole date | |||
(((1582 == year) and (10 <= month) and (12 >= month)) or -- any whole 1582 date from 1 october to 31 December or | |||
((1926 == year) and (1 == month) and (1 == input.day)) or -- 1 January 1926 or | |||
((1582 < year) and (1925 >= year))) then -- any date 1 January 1583 – 31 December 1925 | |||
tCOinS_date.inter_cal_cat = true; -- set category flag true | |||
end | |||
-- end temporary Julian / Gergorian calendar uncertainty detection | |||
if 1582 > tonumber(input.year) or 20 < tonumber(input.month) then -- Julian calendar or season so &rft.date gets year only | if 1582 > tonumber(input.year) or 20 < tonumber(input.month) then -- Julian calendar or season so &rft.date gets year only | ||
Line 282: | Line 294: | ||
end | end | ||
if 20 < tonumber(input.month) then -- if season or propername date | if 20 < tonumber(input.month) then -- if season or propername date | ||
local season = {[ | local season = {[24]='winter', [21]='spring', [22]='summer', [23]='fall', [99]='Christmas'}; -- seasons lowercase, no autumn; proper names use title case | ||
if 0 == input.month2 then -- single season date | if 0 == input.month2 then -- single season date | ||
if 30 <tonumber(input.month) then | if 30 <tonumber(input.month) then | ||
Line 364: | Line 376: | ||
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 | 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; | ||
elseif | elseif mw.ustring.match(date_string, "^%D- +[1-9]%d?, +[1-9]%d%d%d%a?$") then -- month-initial: month day, year | ||
month, day, anchor_year, year= | month, day, anchor_year, year=mw.ustring.match(date_string, "(%D-) +(%d%d?),%s*((%d%d%d%d?)%a?)"); | ||
month = get_month_number (month); | month = get_month_number (month); | ||
if 0 == month then return false; end -- return false if month text isn't one of the twelve months | if 0 == month then return false; end -- return false if month text isn't one of the twelve months | ||
elseif mw.ustring.match(date_string, "^% | elseif mw.ustring.match(date_string, "^%D- +[1-9]%d?[%-–][1-9]%d?, +[1-9]%d%d%d%a?$") then -- month-initial day range: month day–day, year; days are separated by endash | ||
month, day, day2, anchor_year, year=mw.ustring.match(date_string, "(% | month, day, day2, anchor_year, year=mw.ustring.match(date_string, "(%D-) +(%d%d?)[%-–](%d%d?), +((%d%d%d%d)%a?)"); | ||
if tonumber(day) >= tonumber(day2) then return false; end -- date range order is left to right: earlier to later; dates may not be the same; | if tonumber(day) >= tonumber(day2) then return false; end -- date range order is left to right: earlier to later; dates may not be the same; | ||
month = get_month_number (month); | month = get_month_number (month); | ||
Line 377: | Line 389: | ||
year2=year; | year2=year; | ||
elseif | elseif mw.ustring.match(date_string, "^[1-9]%d? +%D- +[1-9]%d%d%d%a?$") then -- day-initial: day month year | ||
day, month, anchor_year, year= | day, month, anchor_year, year=mw.ustring.match(date_string, "(%d%d*)%s*(%D-) +((%d%d%d%d?)%a?)"); | ||
month = get_month_number (month); | month = get_month_number (month); | ||
if 0 == month then return false; end -- return false if month text isn't one of the twelve months | if 0 == month then return false; end -- return false if month text isn't one of the twelve months | ||
elseif mw.ustring.match(date_string, "^[1-9]%d?[%-–][1-9]%d? +% | elseif mw.ustring.match(date_string, "^[1-9]%d?[%-–][1-9]%d? +%D- +[1-9]%d%d%d%a?$") then -- day-range-initial: day–day month year; days are separated by endash | ||
day, day2, month, anchor_year, year=mw.ustring.match(date_string, "(%d%d?)[%-–](%d%d?) +(% | day, day2, month, anchor_year, year=mw.ustring.match(date_string, "(%d%d?)[%-–](%d%d?) +(%D-) +((%d%d%d%d)%a?)"); | ||
if tonumber(day) >= tonumber(day2) then return false; end -- date range order is left to right: earlier to later; dates may not be the same; | if tonumber(day) >= tonumber(day2) then return false; end -- date range order is left to right: earlier to later; dates may not be the same; | ||
month = get_month_number (month); | month = get_month_number (month); | ||
Line 390: | Line 402: | ||
year2=year; | year2=year; | ||
elseif mw.ustring.match(date_string, "^[1-9]%d? +% | elseif mw.ustring.match(date_string, "^[1-9]%d? +%D- +[%-–] +[1-9]%d? +%D- +[1-9]%d%d%d%a?$") then -- day initial month-day-range: day month - day month year; uses spaced endash | ||
day, month, day2, month2, anchor_year, year=mw.ustring.match(date_string, "(%d%d?) +(% | day, month, day2, month2, anchor_year, year=mw.ustring.match(date_string, "(%d%d?) +(%D-) +[%-–] +(%d%d?) +(%D-) +((%d%d%d%d)%a?)"); | ||
if (not is_valid_month_season_range(month, month2)) or not is_valid_year(year) then return false; end -- date range order is left to right: earlier to later; | if (not is_valid_month_season_range(month, month2)) or not is_valid_year(year) then return false; end -- date range order is left to right: earlier to later; | ||
month = get_month_number (month); -- for metadata | month = get_month_number (month); -- for metadata | ||
Line 397: | Line 409: | ||
year2=year; | year2=year; | ||
elseif mw.ustring.match(date_string, "^% | elseif mw.ustring.match(date_string, "^%D- +[1-9]%d? +[%-–] +%D- +[1-9]%d?, +[1-9]%d%d%d%a?$") then -- month initial month-day-range: month day – month day, year; uses spaced endash | ||
month, day, month2, day2, anchor_year, year=mw.ustring.match(date_string, "(% | month, day, month2, day2, anchor_year, year=mw.ustring.match(date_string, "(%D-) +(%d%d?) +[%-–] +(%D-) +(%d%d?), +((%d%d%d%d)%a?)"); | ||
if (not is_valid_month_season_range(month, month2)) or not is_valid_year(year) then return false; end | if (not is_valid_month_season_range(month, month2)) or not is_valid_year(year) then return false; end | ||
month = get_month_number (month); -- for metadata | month = get_month_number (month); -- for metadata | ||
Line 404: | Line 416: | ||
year2=year; | year2=year; | ||
elseif mw.ustring.match(date_string, "^[1-9]%d? +% | elseif mw.ustring.match(date_string, "^[1-9]%d? +%D- +[1-9]%d%d%d +[%-–] +[1-9]%d? +%D- +[1-9]%d%d%d%a?$") then -- day initial month-day-year-range: day month year - day month year; uses spaced endash | ||
day, month, year, day2, month2, anchor_year, year2=mw.ustring.match(date_string, "(%d%d?) +(% | day, month, year, day2, month2, anchor_year, year2=mw.ustring.match(date_string, "(%d%d?) +(%D-) +(%d%d%d%d) +[%-–] +(%d%d?) +(%D-) +((%d%d%d%d)%a?)"); | ||
if tonumber(year2) <= tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later | if tonumber(year2) <= tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later | ||
if not is_valid_year(year2) or not is_valid_month_range_style(month, month2) then return false; end -- year2 no more than one year in the future; months same style | if not is_valid_year(year2) or not is_valid_month_range_style(month, month2) then return false; end -- year2 no more than one year in the future; months same style | ||
Line 411: | Line 423: | ||
month2 = get_month_number (month2); | month2 = get_month_number (month2); | ||
elseif mw.ustring.match(date_string, "^% | elseif mw.ustring.match(date_string, "^%D- +[1-9]%d?, +[1-9]%d%d%d +[%-–] +%D- +[1-9]%d?, +[1-9]%d%d%d%a?$") then -- month initial month-day-year-range: month day, year – month day, year; uses spaced endash | ||
month, day, year, month2, day2, anchor_year, year2=mw.ustring.match(date_string, "(% | month, day, year, month2, day2, anchor_year, year2=mw.ustring.match(date_string, "(%D-) +(%d%d?), +(%d%d%d%d) +[%-–] +(%D-) +(%d%d?), +((%d%d%d%d)%a?)"); | ||
if tonumber(year2) <= tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later | if tonumber(year2) <= tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later | ||
if not is_valid_year(year2) or not is_valid_month_range_style(month, month2) then return false; end -- year2 no more than one year in the future; months same style | if not is_valid_year(year2) or not is_valid_month_range_style(month, month2) then return false; end -- year2 no more than one year in the future; months same style | ||
Line 418: | Line 430: | ||
month2 = get_month_number (month2); | month2 = get_month_number (month2); | ||
elseif mw.ustring.match(date_string, "^% | elseif mw.ustring.match(date_string, "^%D- +[1-9]%d%d%d[%-–]%d%d%a?$") then -- special case Winter/Summer year-year (YYYY-YY); year separated with unspaced endash | ||
local century; | local century; | ||
month, year, century, anchor_year, year2=mw.ustring.match(date_string, "(% | month, year, century, anchor_year, year2=mw.ustring.match(date_string, "(%D-) +((%d%d)%d%d)[%-–]((%d%d)%a?)"); | ||
if 'Winter' ~= month and 'Summer' ~= month then return false end; -- 'month' can only be Winter or Summer | if 'Winter' ~= month and 'Summer' ~= month then return false end; -- 'month' can only be Winter or Summer | ||
anchor_year=year..'–'..anchor_year; -- assemble anchor_year from both years | anchor_year=year..'–'..anchor_year; -- assemble anchor_year from both years | ||
Line 428: | Line 440: | ||
month = get_season_number (month); | month = get_season_number (month); | ||
elseif mw.ustring.match(date_string, "^% | elseif mw.ustring.match(date_string, "^%D- +[1-9]%d%d%d[%-–][1-9]%d%d%d%a?$") then -- special case Winter/Summer year-year; year separated with unspaced endash | ||
month, year, anchor_year, year2=mw.ustring.match(date_string, "(% | month, year, anchor_year, year2=mw.ustring.match(date_string, "(%D-) +(%d%d%d%d)[%-–]((%d%d%d%d)%a?)"); | ||
if 'Winter' ~= month and 'Summer' ~= month then return false end; -- 'month' can only be Winter or Summer | if 'Winter' ~= month and 'Summer' ~= month then return false end; -- 'month' can only be Winter or Summer | ||
anchor_year=year..'–'..anchor_year; -- assemble anchor_year from both years | anchor_year=year..'–'..anchor_year; -- assemble anchor_year from both years | ||
Line 436: | Line 448: | ||
month = get_season_number (month); -- for metadata | month = get_season_number (month); -- for metadata | ||
elseif mw.ustring.match(date_string, "^% | elseif mw.ustring.match(date_string, "^%D- +[1-9]%d%d%d +[%-–] +%D- +[1-9]%d%d%d%a?$") then -- month/season year - month/season year; separated by spaced endash | ||
month, year, month2, anchor_year, year2=mw.ustring.match(date_string, "(% | month, year, month2, anchor_year, year2=mw.ustring.match(date_string, "(%D-) +(%d%d%d%d) +[%-–] +(%D-) +((%d%d%d%d)%a?)"); | ||
anchor_year=year..'–'..anchor_year; -- assemble anchor_year from both years | anchor_year=year..'–'..anchor_year; -- assemble anchor_year from both years | ||
if tonumber(year) >= tonumber(year2) then return false; end -- left to right, earlier to later, not the same | if tonumber(year) >= tonumber(year2) then return false; end -- left to right, earlier to later, not the same | ||
Line 451: | Line 463: | ||
end | end | ||
elseif mw.ustring.match(date_string, "^% | elseif mw.ustring.match(date_string, "^%D-[%-–]%D- +[1-9]%d%d%d%a?$") then -- month/season range year; months separated by endash | ||
month, month2, anchor_year, year=mw.ustring.match(date_string, "(% | month, month2, anchor_year, year=mw.ustring.match(date_string, "(%D-)[%-–](%D-)%s*((%d%d%d%d)%a?)"); | ||
if (not is_valid_month_season_range(month, month2)) or (not is_valid_year(year)) then return false; end | if (not is_valid_month_season_range(month, month2)) or (not is_valid_year(year)) then return false; end | ||
if 0 ~= get_month_number(month) then -- determined to be a valid range so just check this one to know if month or season | if 0 ~= get_month_number(month) then -- determined to be a valid range so just check this one to know if month or season | ||
Line 463: | Line 475: | ||
year2=year; | year2=year; | ||
elseif | elseif mw.ustring.match(date_string, "^%D- +%d%d%d%d%a?$") then -- month/season year or proper-name year | ||
month, anchor_year, year= | month, anchor_year, year=mw.ustring.match(date_string, "(%D-)%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) and 0 == is_proper_name (month) then return false; end | if not is_valid_month_or_season (month) and 0 == is_proper_name (month) then return false; end | ||
Line 559: | Line 571: | ||
if is_set(v) then -- if the parameter has a value | if is_set(v) then -- if the parameter has a value | ||
if v:match("^c%. [1-9]%d%d%d?%a?$") then -- special case for c. year or with or without CITEREF disambiguator - only |date= and |year= | if v:match("^c%. [1-9]%d%d%d?%a?$") then -- special case for c. year or with or without CITEREF disambiguator - only |date= and |year= | ||
v = mw.ustring.gsub (v, '%d', cfg.date_names.local_digits); | |||
local year = v:match("c%. ([1-9]%d%d%d?)%a?"); -- get the year portion so it can be tested | local year = v:match("c%. ([1-9]%d%d%d?)%a?"); -- get the year portion so it can be tested | ||
if 'date'==k then | if 'date'==k then |