Changes
]]
local is_set, in_array; -- imported function functions from selected Module:Citation/CS1/Utilitieslocal cfg; -- table of tables imported from slected Module:Citation/CS1/Configuration
--[=[-------------------------< I S _ V A L I D _ A C C E S S D A T E >----------------------------------------
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 -- lang.formatDate() returns a timestamp in the local script which which tonumber() may not understand access_ts = tonumber (access_ts) or lang:parseFormattedNumber (access_ts); -- convert to numbers for the comparison; tomorrow_ts = tonumber (tomorrow_ts) or lang:parseFormattedNumber (tomorrow_ts);
else
return false; -- one or both failed to convert to unix time stamp
local function get_month_number (month)
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
Uses ISO DIS 8601 2016 part 2 §4.7 Divisions of a year for hemishpere-independent seasons:
21-24 = Spring, Summer, Autumn, Winter, independent of “Hemisphere”
These additional divisions not currently supported:
25-28 = Spring - Northern Hemisphere, Summer- Northern Hemisphere, Autumn - Northern Hemisphere, Winter - Northern Hemisphere
29-32 = Spring – Southern Hemisphere, Summer– Southern Hemisphere, Autumn – Southern Hemisphere, Winter - Southern Hemisphere
33-36 = Quarter 1, Quarter 2, Quarter 3, Quarter 4 (3 months each)
37-39 = Quadrimester 1, Quadrimester 2, Quadrimester 3 (4 months each)
40-41 = Semestral 1, Semestral-2 (6 months each)
]]
local function get_season_number (season)
end
local function is_proper_name (name)
end
Month pairs are expected to be left to right, earliest to latest in time.
]]
if 0 == range_start_number then -- is this a month range?
range_end_number = get_season_number (range_end); -- get end season number
if (0 ~= range_start_number ) and (0 ~= range_end_number) then -- is start of range a season? if range_start_number < range_end_number then -- range_start is a season return true; -- return true when range_end is also a any season and follows start season; else false end if 24 == range_start_number and 21 == range_end_number then -- special case when season range pairing is Fall-Winter or Autumn-Winter return true; endaccepted
end
return false; -- range_start is not a month and/or a season; or range_start is a season and range_end is not; or improper a season sequence
end
-- here when range_start is a month
range_end_number = get_month_number (range_end); -- get end month number
if range_start_number < range_end_number then -- range_start is a month; does range_start precede range_end?
The input table has:
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; 31– proper name dates99 Christmas
day, day2 – 0 if not provided, 1-31 for days
local date; -- one date or first date in a range
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
end
if 20 < tonumber(input.month) then -- if season or propername date
local season = {[2124]='winter', [2221]='spring', [2322]='summer', [2423]='fall', [3199]='Christmas'}; -- seasons lowercase, no autumn; proper names use title case
if 0 == input.month2 then -- single season date
if 30 <tonumber(input.month) then
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;
elseif date_string:mw.ustring.match(date_string, "^%a+ D- +[1-9]%d?, +[1-9]%d%d%d%a?$") then -- month-initial: month day, year month, day, anchor_year, year=stringmw.ustring.match(date_string, "(%aD-) +)%s*(%d%d?),%s*((%d%d%d%d?)%a?)");
month = get_month_number (month);
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, "^%a+ 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, "(%a+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;
month = get_month_number (month);
year2=year;
elseif date_string:mw.ustring.match(date_string, "^[1-9]%d? +%a+ D- +[1-9]%d%d%d%a?$") then -- day-initial: day month year day, month, anchor_year, year=stringmw.ustring.match(date_string, "(%d%d*)%s*(%a+D-)%s*+((%d%d%d%d?)%a?)");
month = get_month_number (month);
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? +%a+ 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?) +(%a+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;
month = get_month_number (month);
year2=year;
elseif mw.ustring.match(date_string, "^[1-9]%d? +%aD- + [%-–] +[1-9]%d? +%a+ 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?) +(%a+D-) +[%-–] +(%d%d?) +(%a+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;
month = get_month_number (month); -- for metadata
year2=year;
elseif mw.ustring.match(date_string, "^%a+ D- +[1-9]%d? +[%-–] %a+ %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, "(%a+D-) +(%d%d?) +[%-–] +(%a+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
month = get_month_number (month); -- for metadata
year2=year;
elseif mw.ustring.match(date_string, "^[1-9]%d? +%a+ D- +[1-9]%d%d%d +[%-–] +[1-9]%d? +%a+ 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?) +(%a+D-) +(%d%d%d%d?) +[%-–] +(%d%d?) +(%a+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 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
month2 = get_month_number (month2);
elseif mw.ustring.match(date_string, "^%a+ D- +[1-9]%d?, +[1-9]%d%d%d +[%-–] %a+ %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, "(%a+D-) +(%d%d?), +(%d%d%d%d) +[%-–] +(%a+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 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
month2 = get_month_number (month2);
elseif mw.ustring.match(date_string, "^%a+ 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;
month, year, century, anchor_year, year2=mw.ustring.match(date_string, "(%a+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
anchor_year=year..'–'..anchor_year; -- assemble anchor_year from both years
month = get_season_number (month);
elseif mw.ustring.match(date_string, "^%a+ 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, "(%a+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
anchor_year=year..'–'..anchor_year; -- assemble anchor_year from both years
month = get_season_number (month); -- for metadata
elseif mw.ustring.match(date_string, "^%a+ D- +[1-9]%d%d%d +[%-–] +%a+ 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, "(%a+D-) +(%d%d%d%d) +[%-–] +(%a+D-) +((%d%d%d%d)%a?)");
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
end
elseif mw.ustring.match(date_string, "^%a+D-[%-–]%a+ 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, "(%a+D-)[%-–](%a+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 0 ~= get_month_number(month) then -- determined to be a valid range so just check this one to know if month or season
year2=year;
elseif date_string:mw.ustring.match(date_string, "^%a+ D- +%d%d%d%d%a?$") then -- month/season year or proper-name year month, anchor_year, year=date_string:mw.ustring.match(date_string, "(%a+D-)%s*((%d%d%d%d)%a?)");
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 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=
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
if 'date'==k then
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)$',
}
Date ranges, season dates, proper name dates are not currently supported.
For i18n: This code works only at en.wiki because os.date() doesn't support any languages other than English.
mw.getContentLanguage():formatDate() will work at non-English wikis only when the date format is yyyy-mm-dd. This is
the same issue that plagues is_valid_accessdate()
It is possible that a solution like that written for ht:Module:Citation/CS1/Date_validation date_name_xlate() could be applied to this problem
]]
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
end
end
return result; -- so we know if any hyphens were replaced
end
--[[-------------------------< D A T E _ N A M E _ X L A T E >------------------------------------------------
Attempts to translate English month names to local-language month names using names supplied by MediaWiki's
date parser function. This is simple name-for-name replacement and may not work for all languages.
]]
local function date_name_xlate (date_parameters_list)
local xlate;
local mode; -- long or short month names
local modified = false;
local date;
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
date = param_val;
for month in mw.ustring.gmatch (date, '%a+') do -- iterate through all dates in the date (single date or date range)
if cfg.date_names.en.long[month] then
mode = 'F'; -- English name is long so use long local name
elseif cfg.date_names.en.short[month] then
mode = 'M'; -- English name is short so use short local name
else
mode = nil; -- not an English month name; could be local language month name or an English season name
end
if mode then -- might be a season
xlate = mw.getContentLanguage():formatDate(mode, '1' .. month); -- translate the month name to this local language
date = mw.ustring.gsub (date, month, xlate); -- replace the English with the translation
date_parameters_list[param_name] = date; -- save the translated date
modified = true;
end
end
end
end
return modified;
end
]]
local function set_selected_modules (cfg_table_ptr, utilities_page_ptr) is_set = utilities_page_ptr.is_set; -- import functions from select selected Module:Citation/CS1/Utilities module in_array = utilities_page_ptr.in_array; -- import functions from select selected Module:Citation/CS1/Utilities module cfg = cfg_table_ptr; -- import tables from selected Module:Citation/CS1/Configuration
end
reformat_dates = reformat_dates,
date_hyphen_to_dash = date_hyphen_to_dash,
date_name_xlate = date_name_xlate,
set_selected_modules = set_selected_modules
}
Anonymous user