<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ar">
	<id>https://www.arabsciencepedia.org/w/index.php?action=history&amp;feed=atom&amp;title=%D9%88%D8%AD%D8%AF%D8%A9%3ACitation%2FCS1%2FDate_validation%2Fdoc</id>
	<title>وحدة:Citation/CS1/Date validation/doc - تاريخ المراجعة</title>
	<link rel="self" type="application/atom+xml" href="https://www.arabsciencepedia.org/w/index.php?action=history&amp;feed=atom&amp;title=%D9%88%D8%AD%D8%AF%D8%A9%3ACitation%2FCS1%2FDate_validation%2Fdoc"/>
	<link rel="alternate" type="text/html" href="https://www.arabsciencepedia.org/w/index.php?title=%D9%88%D8%AD%D8%AF%D8%A9:Citation/CS1/Date_validation/doc&amp;action=history"/>
	<updated>2026-05-04T09:00:24Z</updated>
	<subtitle>تاريخ التعديل لهذه الصفحة في الويكي</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://www.arabsciencepedia.org/w/index.php?title=%D9%88%D8%AD%D8%AF%D8%A9:Citation/CS1/Date_validation/doc&amp;diff=36870&amp;oldid=prev</id>
		<title>أسيل سيوف: أنشأ الصفحة ب&#039; local p = {}  ----------------------------&lt; I S _ V A L I D _ A C C E S S D A T E &gt;----------------------------------------  returns true if: 	Wikipedia start date &lt;=...&#039;</title>
		<link rel="alternate" type="text/html" href="https://www.arabsciencepedia.org/w/index.php?title=%D9%88%D8%AD%D8%AF%D8%A9:Citation/CS1/Date_validation/doc&amp;diff=36870&amp;oldid=prev"/>
		<updated>2015-12-11T10:40:03Z</updated>

		<summary type="html">&lt;p&gt;أنشأ الصفحة ب&amp;#039; local p = {}  ----------------------------&amp;lt; I S _ V A L I D _ A C C E S S D A T E &amp;gt;----------------------------------------  returns true if: 	Wikipedia start date &amp;lt;=...&amp;#039;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;صفحة جديدة&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I S _ V A L I D _ A C C E S S D A T E &amp;gt;----------------------------------------&lt;br /&gt;
&lt;br /&gt;
returns true if:&lt;br /&gt;
	Wikipedia start date &amp;lt;= accessdate &amp;lt; today + 2 days&lt;br /&gt;
&lt;br /&gt;
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)&lt;br /&gt;
accessdate is the date provided in |accessdate= at time 00:00:00 UTC&lt;br /&gt;
today is the current date at time 00:00:00 UTC plus 48 hours&lt;br /&gt;
	if today is 2015-01-01T00:00:00 then&lt;br /&gt;
		adding 24 hours gives 2015-01-02T00:00:00 – one second more than today&lt;br /&gt;
		adding 24 hours gives 2015-01-03T00:00:00 – one second more than tomorrow&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function is_valid_accessdate (accessdate)&lt;br /&gt;
	local lang = mw.getContentLanguage();&lt;br /&gt;
	local good1, good2;&lt;br /&gt;
	local access_ts, tomorrow_ts;												-- to hold unix time stamps representing the dates&lt;br /&gt;
		&lt;br /&gt;
	good1, access_ts = pcall( lang.formatDate, lang, &amp;#039;U&amp;#039;, accessdate );			-- convert accessdate value to unix timesatmp &lt;br /&gt;
	good2, tomorrow_ts = pcall( lang.formatDate, lang, &amp;#039;U&amp;#039;, &amp;#039;today + 2 days&amp;#039; );	-- today midnight + 2 days is one second more than all day tomorrow&lt;br /&gt;
	&lt;br /&gt;
	if good1 and good2 then&lt;br /&gt;
		access_ts = tonumber (access_ts);										-- convert to numbers for the comparison&lt;br /&gt;
		tomorrow_ts = tonumber (tomorrow_ts);&lt;br /&gt;
	else&lt;br /&gt;
		return false;															-- one or both failed to convert to unix time stamp&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if 979516800 &amp;lt;= access_ts and access_ts &amp;lt; tomorrow_ts then					-- Wikipedia start date &amp;lt;= accessdate &amp;lt; tomorrow&amp;#039;s date&lt;br /&gt;
		return true;&lt;br /&gt;
	else&lt;br /&gt;
		return false;															-- accessdate out of range&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; G E T _ M O N T H _ N U M B E R &amp;gt;----------------------------------------------&lt;br /&gt;
&lt;br /&gt;
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&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function get_month_number (month)&lt;br /&gt;
local long_months = {[&amp;#039;January&amp;#039;]=1, [&amp;#039;February&amp;#039;]=2, [&amp;#039;March&amp;#039;]=3, [&amp;#039;April&amp;#039;]=4, [&amp;#039;May&amp;#039;]=5, [&amp;#039;June&amp;#039;]=6, [&amp;#039;July&amp;#039;]=7, [&amp;#039;August&amp;#039;]=8, [&amp;#039;September&amp;#039;]=9, [&amp;#039;October&amp;#039;]=10, [&amp;#039;November&amp;#039;]=11, [&amp;#039;December&amp;#039;]=12};&lt;br /&gt;
local short_months = {[&amp;#039;Jan&amp;#039;]=1, [&amp;#039;Feb&amp;#039;]=2, [&amp;#039;Mar&amp;#039;]=3, [&amp;#039;Apr&amp;#039;]=4, [&amp;#039;May&amp;#039;]=5, [&amp;#039;Jun&amp;#039;]=6, [&amp;#039;Jul&amp;#039;]=7, [&amp;#039;Aug&amp;#039;]=8, [&amp;#039;Sep&amp;#039;]=9, [&amp;#039;Oct&amp;#039;]=10, [&amp;#039;Nov&amp;#039;]=11, [&amp;#039;Dec&amp;#039;]=12};&lt;br /&gt;
local temp;&lt;br /&gt;
	temp=long_months[month];&lt;br /&gt;
	if temp then return temp; end				-- if month is the long-form name&lt;br /&gt;
	temp=short_months[month];&lt;br /&gt;
	if temp then return temp; end				-- if month is the short-form name&lt;br /&gt;
	return 0;									-- misspelled, improper case, or not a month name&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; G E T _ S E A S O N _ N U M B E R &amp;gt;--------------------------------------------&lt;br /&gt;
&lt;br /&gt;
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&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function get_season_number (season)&lt;br /&gt;
local season_list = {[&amp;#039;Winter&amp;#039;]=21, [&amp;#039;Spring&amp;#039;]=22, [&amp;#039;Summer&amp;#039;]=23, [&amp;#039;Fall&amp;#039;]=24, [&amp;#039;Autumn&amp;#039;]=24};	-- make sure these numbers do not overlap month numbers&lt;br /&gt;
local temp;&lt;br /&gt;
	temp=season_list[season];&lt;br /&gt;
	if temp then return temp; end												-- if season is a valid name return its number&lt;br /&gt;
	return 0;																	-- misspelled, improper case, or not a season name&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I S _ P R O P E R _ N A M E &amp;gt;--------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
returns a non-zero number if date contains a recognized proper name.  Capitalization and spelling must be correct.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function is_proper_name (name)&lt;br /&gt;
local name_list = {[&amp;#039;Christmas&amp;#039;]=31}&lt;br /&gt;
local temp;&lt;br /&gt;
	temp=name_list[name];&lt;br /&gt;
	if temp then return temp; end				-- if name is a valid name return its number&lt;br /&gt;
	return 0;									-- misspelled, improper case, or not a proper name&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I S _ V A L I D _ M O N T H _ O R _ S E A S O N &amp;gt;------------------------------&lt;br /&gt;
&lt;br /&gt;
--returns true if month or season is valid (properly spelled, capitalized, abbreviated)&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function is_valid_month_or_season (month_season)&lt;br /&gt;
	if 0 == get_month_number (month_season) then		-- if month text isn&amp;#039;t one of the twelve months, might be a season&lt;br /&gt;
		if 0 == get_season_number (month_season) then	-- not a month, is it a season?&lt;br /&gt;
			return false;								-- return false not a month or one of the five seasons&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return true;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I S _ V A L I D _ Y E A R &amp;gt;----------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Function gets current year from the server and compares it to year from a citation parameter.  Years more than one year in the future are not acceptable.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function is_valid_year(year)&lt;br /&gt;
	if not is_set(year_limit) then&lt;br /&gt;
		year_limit = tonumber(os.date(&amp;quot;%Y&amp;quot;))+1;			-- global variable so we only have to fetch it once&lt;br /&gt;
	end&lt;br /&gt;
	return tonumber(year) &amp;lt;= year_limit;				-- false if year is in the future more than one year&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Returns true if day is less than or equal to the number of days in month and year is no farther into the future than next year; else returns false.&lt;br /&gt;
&lt;br /&gt;
Assumes Julian calendar prior to year 1582 and Gregorian calendar thereafter. Accounts for Julian calendar leap years before 1582 and Gregorian leap years after 1582.&lt;br /&gt;
Where the two calendars overlap (1582 to approximately 1923) dates are assumed to be Gregorian.&lt;br /&gt;
]]&lt;br /&gt;
local function is_valid_date (year, month, day)&lt;br /&gt;
local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};&lt;br /&gt;
local month_length;&lt;br /&gt;
	if not is_valid_year(year) then	-- no farther into the future than next year&lt;br /&gt;
		return false;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if (2==month) then							-- if February&lt;br /&gt;
		month_length = 28;						-- then 28 days unless&lt;br /&gt;
		if 1582 &amp;gt; tonumber(year) then			-- Julian calendar&lt;br /&gt;
			if 0==(year%4) then&lt;br /&gt;
				month_length = 29;&lt;br /&gt;
			end&lt;br /&gt;
		else									-- Gregorian calendar&lt;br /&gt;
			if (0==(year%4) and (0~=(year%100) or 0==(year%400))) then	-- is a leap year?&lt;br /&gt;
				month_length = 29;				-- if leap year then 29 days in February&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		month_length=days_in_month[tonumber(month)];&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if tonumber (day) &amp;gt; month_length then&lt;br /&gt;
		return false;&lt;br /&gt;
	end&lt;br /&gt;
	return true;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I S _ V A L I D _ M O N T H _ R A N G E _ S T Y L E &amp;gt;--------------------------&lt;br /&gt;
&lt;br /&gt;
Months in a range are expected to have the same style: Jan–Mar or October–December but not February–Mar or Jul–August. &lt;br /&gt;
There is a special test for May because it can be either short or long form.&lt;br /&gt;
&lt;br /&gt;
Returns true when style for both months is the same&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function is_valid_month_range_style (month1, month2)&lt;br /&gt;
local len1 = month1:len();&lt;br /&gt;
local len2 = month2:len();&lt;br /&gt;
	if len1 == len2 then&lt;br /&gt;
		return true;															-- both months are short form so return true&lt;br /&gt;
	elseif &amp;#039;May&amp;#039; == month1 or &amp;#039;May&amp;#039;== month2 then&lt;br /&gt;
		return true;															-- both months are long form so return true&lt;br /&gt;
	elseif 3 == len1 or 3 == len2 then&lt;br /&gt;
		return false;															-- months are mixed form so return false&lt;br /&gt;
	else&lt;br /&gt;
		return true;															-- both months are long form so return true&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I S _ V A L I D _ M O N T H _ S E A S O N _ R A N G E &amp;gt;------------------------&lt;br /&gt;
&lt;br /&gt;
Check a pair of months or seasons to see if both are valid members of a month or season pair.&lt;br /&gt;
&lt;br /&gt;
Month pairs are expected to be left to right, earliest to latest in time.&lt;br /&gt;
&lt;br /&gt;
Similarly, seasons are also left to right, earliest to latest in time.  There is an oddity with seasons: winter is assigned a value of 1, spring 2, ...,&lt;br /&gt;
fall and autumn 4.  Because winter can follow fall/autumn at the end of a calender year, a special test is made to see if |date=Fall-Winter yyyy (4-1) is the date.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function is_valid_month_season_range(range_start, range_end)&lt;br /&gt;
	local range_start_number = get_month_number (range_start);&lt;br /&gt;
	&lt;br /&gt;
	if 0 == range_start_number then												-- is this a month range?&lt;br /&gt;
		local range_start_number = get_season_number (range_start);				-- not a month; is it a season? get start season number&lt;br /&gt;
		local range_end_number = get_season_number (range_end);					-- get end season number&lt;br /&gt;
&lt;br /&gt;
		if 0 ~= range_start_number then											-- is start of range a season?&lt;br /&gt;
			if range_start_number &amp;lt; range_end_number then						-- range_start is a season&lt;br /&gt;
				return true;													-- return true when range_end is also a season and follows start season; else false&lt;br /&gt;
			end&lt;br /&gt;
			if 24 == range_start_number and 21 == range_end_number then			-- special case when season range is Fall-Winter or Autumn-Winter&lt;br /&gt;
				return true;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return false;		-- range_start is not a month or a season; or range_start is a season and range_end is not; or improper season sequence&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local range_end_number = get_month_number (range_end);						-- get end month number&lt;br /&gt;
	if range_start_number &amp;lt; range_end_number then								-- range_start is a month; does range_start precede range_end?&lt;br /&gt;
		if is_valid_month_range_style (range_start, range_end) then				-- do months have the same style?&lt;br /&gt;
			return true;														-- proper order and same style&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false;																-- range_start month number is greater than or equal to range end number; or range end isn&amp;#039;t a month&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; M A K E _ C O I N S _ D A T E &amp;gt;------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
This function receives a table of date parts for one or two dates and an empty table reference declared in&lt;br /&gt;
Module:Citation/CS1.  The function is called only for |date= parameters and only if the |date=&amp;lt;value&amp;gt; is &lt;br /&gt;
determined to be a valid date format.  The question of what to do with invlaid date formats is not answered here.&lt;br /&gt;
&lt;br /&gt;
The date parts in the input table are converted to an ISO 8601 conforming date string:&lt;br /&gt;
	single whole dates:		yyyy-mm-dd&lt;br /&gt;
	month and year dates:	yyyy-mm&lt;br /&gt;
	year dates:				yyyy&lt;br /&gt;
	ranges:					yyyy-mm-dd/yyyy-mm-dd&lt;br /&gt;
							yyyy-mm/yyyy-mm&lt;br /&gt;
							yyyy/yyyy&lt;br /&gt;
&lt;br /&gt;
Dates in the Julian calendar are reduced to year or year/year so that we don&amp;#039;t have to do calendar conversion from&lt;br /&gt;
Julian to Proleptic Gregorian.&lt;br /&gt;
&lt;br /&gt;
The input table has:&lt;br /&gt;
	year, year2 – always present; if before 1582, ignore months and days if present&lt;br /&gt;
	month, month2 – 0 if not provided, 1-12 for months, 21-24 for seasons; 31– proper name dates&lt;br /&gt;
	day, day2 –  0 if not provided, 1-31 for days&lt;br /&gt;
	&lt;br /&gt;
the output table receives:&lt;br /&gt;
	rftdate:	an IS8601 formatted date&lt;br /&gt;
	rftchron:	a free-form version of the date, usually without year which is in rftdate (season ranges and propername dates)&lt;br /&gt;
	rftssn:		one of four season keywords: winter, spring, summer, fall (lowercase)&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function make_COinS_date (input, tCOinS_date)&lt;br /&gt;
	local date;																	-- one date or first date in a range&lt;br /&gt;
	local date2 = &amp;#039;&amp;#039;;															-- end of range date&lt;br /&gt;
	&lt;br /&gt;
	if 1582 &amp;gt; tonumber(input.year) or 20 &amp;lt; tonumber(input.month) then			-- Julian calendar or season so &amp;amp;rft.date gets year only&lt;br /&gt;
		date = input.year;&lt;br /&gt;
		if 0 ~= input.year2 and input.year ~= input.year2 then					-- if a range, only the second year portion when not the same as range start year&lt;br /&gt;
			date = string.format (&amp;#039;%.4d/%.4d&amp;#039;, tonumber(input.year), tonumber(input.year2))		-- assemble the date range&lt;br /&gt;
		end&lt;br /&gt;
		if 20 &amp;lt; tonumber(input.month) then										-- if season or propername date&lt;br /&gt;
			local season = {[21]=&amp;#039;winter&amp;#039;, [22]=&amp;#039;spring&amp;#039;, [23]=&amp;#039;summer&amp;#039;, [24]=&amp;#039;fall&amp;#039;, [31]=&amp;#039;Christmas&amp;#039;};	-- seasons lowercase, no autumn; proper names use title case&lt;br /&gt;
			if 0 == input.month2 then											-- single season date&lt;br /&gt;
				if 30 &amp;lt;tonumber(input.month) then&lt;br /&gt;
					tCOinS_date.rftchron = season[input.month];					-- proper name dates&lt;br /&gt;
				else&lt;br /&gt;
					tCOinS_date.rftssn = season[input.month];					-- seasons&lt;br /&gt;
				end&lt;br /&gt;
			else																-- season range with a second season specified&lt;br /&gt;
				if input.year ~= input.year2 then								-- season year – season year range or season year–year&lt;br /&gt;
					tCOinS_date.rftssn = season[input.month];					-- start of range season; keep this?&lt;br /&gt;
					if 0~= month2 then&lt;br /&gt;
						tCOinS_date.rftchron = string.format (&amp;#039;%s %s – %s %s&amp;#039;, season[input.month], input.year, season[input.month2], input.year2);&lt;br /&gt;
					end&lt;br /&gt;
				else															-- season–season year range&lt;br /&gt;
					tCOinS_date.rftssn = season[input.month];					-- start of range season; keep this?&lt;br /&gt;
					tCOinS_date.rftchron = season[input.month] .. &amp;#039;–&amp;#039; .. season[input.month2];	-- season–season year range&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		tCOinS_date.rftdate = date;&lt;br /&gt;
		return;																	-- done&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if 0 ~= input.day then&lt;br /&gt;
		date = string.format (&amp;#039;%s-%.2d-%.2d&amp;#039;, input.year, tonumber(input.month), tonumber(input.day));	-- whole date&lt;br /&gt;
	elseif 0 ~= input.month then&lt;br /&gt;
		date = string.format (&amp;#039;%s-%.2d&amp;#039;, input.year, tonumber(input.month));	-- year and month&lt;br /&gt;
	else&lt;br /&gt;
		date = string.format (&amp;#039;%s&amp;#039;, input.year);								-- just year&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if 0 ~= input.year2 then&lt;br /&gt;
		if 0 ~= input.day2 then&lt;br /&gt;
			date2 = string.format (&amp;#039;/%s-%.2d-%.2d&amp;#039;, input.year2, tonumber(input.month2), tonumber(input.day2));		-- whole date&lt;br /&gt;
		elseif 0 ~= input.month2 then&lt;br /&gt;
			date2 = string.format (&amp;#039;/%s-%.2d&amp;#039;, input.year2, tonumber(input.month2));	-- year and month&lt;br /&gt;
		else&lt;br /&gt;
			date2 = string.format (&amp;#039;/%s&amp;#039;, input.year2);							-- just year&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	tCOinS_date.rftdate = date .. date2;										-- date2 has the &amp;#039;/&amp;#039; separator&lt;br /&gt;
	return;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; C H E C K _ D A T E &amp;gt;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
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&lt;br /&gt;
character abbreviations, and seasons must be spelled correctly. Future years beyond next year are not allowed.&lt;br /&gt;
&lt;br /&gt;
If the date fails the format tests, this function returns false and does not return values for anchor_year and COinS_date.  When this happens, the date parameter is&lt;br /&gt;
used in the COinS metadata and the CITEREF identifier gets its year from the year parameter if present otherwise CITEREF does not get a date value.&lt;br /&gt;
&lt;br /&gt;
Inputs:&lt;br /&gt;
	date_string - date string from date-holding parameters (date, year, accessdate, embargo, archivedate, etc.)&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
	false if date string is not a real date; else&lt;br /&gt;
	true, anchor_year, COinS_date&lt;br /&gt;
		anchor_year can be used in CITEREF anchors&lt;br /&gt;
		COinS_date is date_string without anchor_year disambiguator if any		-- this is being obsoleted.  In future:&lt;br /&gt;
		COinS_date is ISO 8601 format date; see make_COInS_date()&lt;br /&gt;
]]&lt;br /&gt;
local function check_date (date_string, tCOinS_date)&lt;br /&gt;
	local year;			-- assume that year2, months, and days are not used;&lt;br /&gt;
	local year2=0;		-- second year in a year range&lt;br /&gt;
	local month=0;&lt;br /&gt;
	local month2=0;		-- second month in a month range&lt;br /&gt;
	local day=0;&lt;br /&gt;
	local day2=0;		-- second day in a day range&lt;br /&gt;
	local anchor_year;&lt;br /&gt;
	local coins_date;&lt;br /&gt;
&lt;br /&gt;
	if date_string:match(&amp;quot;^%d%d%d%d%-%d%d%-%d%d$&amp;quot;) then										-- year-initial numerical year month day format&lt;br /&gt;
		year, month, day=string.match(date_string, &amp;quot;(%d%d%d%d)%-(%d%d)%-(%d%d)&amp;quot;);&lt;br /&gt;
		if 12 &amp;lt; tonumber(month) or 1 &amp;gt; tonumber(month) or 1583 &amp;gt; tonumber(year) then return false; end			-- month number not valid or not Gregorian calendar&lt;br /&gt;
		anchor_year = year;&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match(&amp;quot;^%a+ +[1-9]%d?, +[1-9]%d%d%d%a?$&amp;quot;) then						-- month-initial: month day, year&lt;br /&gt;
		month, day, anchor_year, year=string.match(date_string, &amp;quot;(%a+)%s*(%d%d?),%s*((%d%d%d%d)%a?)&amp;quot;);&lt;br /&gt;
		month = get_month_number (month);&lt;br /&gt;
		if 0 == month then return false; end												-- return false if month text isn&amp;#039;t one of the twelve months&lt;br /&gt;
				&lt;br /&gt;
	elseif date_string:match(&amp;quot;^%a+ +[1-9]%d?–[1-9]%d?, +[1-9]%d%d%d%a?$&amp;quot;) then				-- month-initial day range: month day–day, year; days are separated by endash&lt;br /&gt;
		month, day, day2, anchor_year, year=string.match(date_string, &amp;quot;(%a+) +(%d%d?)–(%d%d?), +((%d%d%d%d)%a?)&amp;quot;);&lt;br /&gt;
		if tonumber(day) &amp;gt;= tonumber(day2) then return false; end							-- date range order is left to right: earlier to later; dates may not be the same;&lt;br /&gt;
		month = get_month_number (month);&lt;br /&gt;
		if 0 == month then return false; end												-- return false if month text isn&amp;#039;t one of the twelve months&lt;br /&gt;
		month2=month;																		-- for metadata&lt;br /&gt;
		year2=year;&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match(&amp;quot;^[1-9]%d? +%a+ +[1-9]%d%d%d%a?$&amp;quot;) then						-- day-initial: day month year&lt;br /&gt;
		day, month, anchor_year, year=string.match(date_string, &amp;quot;(%d%d*)%s*(%a+)%s*((%d%d%d%d)%a?)&amp;quot;);&lt;br /&gt;
		month = get_month_number (month);&lt;br /&gt;
		if 0 == month then return false; end												-- return false if month text isn&amp;#039;t one of the twelve months&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match(&amp;quot;^[1-9]%d?–[1-9]%d? +%a+ +[1-9]%d%d%d%a?$&amp;quot;) then				-- day-range-initial: day–day month year; days are separated by endash&lt;br /&gt;
		day, day2, month, anchor_year, year=string.match(date_string, &amp;quot;(%d%d?)–(%d%d?) +(%a+) +((%d%d%d%d)%a?)&amp;quot;);&lt;br /&gt;
		if tonumber(day) &amp;gt;= tonumber(day2) then return false; end							-- date range order is left to right: earlier to later; dates may not be the same;&lt;br /&gt;
		month = get_month_number (month);&lt;br /&gt;
		if 0 == month then return false; end												-- return false if month text isn&amp;#039;t one of the twelve months&lt;br /&gt;
		month2=month;																		-- for metadata&lt;br /&gt;
		year2=year;&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match(&amp;quot;^[1-9]%d? +%a+ – [1-9]%d? +%a+ +[1-9]%d%d%d%a?$&amp;quot;) then		-- day initial month-day-range: day month - day month year; uses spaced endash&lt;br /&gt;
		day, month, day2, month2, anchor_year, year=date_string:match(&amp;quot;(%d%d?) +(%a+) – (%d%d?) +(%a+) +((%d%d%d%d)%a?)&amp;quot;);&lt;br /&gt;
		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;&lt;br /&gt;
		month = get_month_number (month);													-- for metadata&lt;br /&gt;
		month2 = get_month_number (month2);&lt;br /&gt;
		year2=year;&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match(&amp;quot;^%a+ +[1-9]%d? – %a+ +[1-9]%d?, +[1-9]%d%d%d?%a?$&amp;quot;) then		-- month initial month-day-range: month day – month day, year;  uses spaced endash&lt;br /&gt;
		month, day, month2, day2, anchor_year, year=date_string:match(&amp;quot;(%a+) +(%d%d?) – (%a+) +(%d%d?), +((%d%d%d%d)%a?)&amp;quot;);&lt;br /&gt;
		if (not is_valid_month_season_range(month, month2)) or not is_valid_year(year) then return false; end&lt;br /&gt;
		month = get_month_number (month);													-- for metadata&lt;br /&gt;
		month2 = get_month_number (month2);&lt;br /&gt;
		year2=year;&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match(&amp;quot;^[1-9]%d? +%a+ +[1-9]%d%d%d – [1-9]%d? +%a+ +[1-9]%d%d%d%a?$&amp;quot;) then		-- day initial month-day-year-range: day month year - day month year; uses spaced endash&lt;br /&gt;
		day, month, year, day2, month2, anchor_year, year2=date_string:match(&amp;quot;(%d%d?) +(%a+) +(%d%d%d%d?) – (%d%d?) +(%a+) +((%d%d%d%d?)%a?)&amp;quot;);&lt;br /&gt;
		if tonumber(year2) &amp;lt;= tonumber(year) then return false; end												-- must be sequential years, left to right, earlier to later&lt;br /&gt;
		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&lt;br /&gt;
		month = get_month_number (month);																		-- for metadata&lt;br /&gt;
		month2 = get_month_number (month2);&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match(&amp;quot;^%a+ +[1-9]%d?, +[1-9]%d%d%d – %a+ +[1-9]%d?, +[1-9]%d%d%d%a?$&amp;quot;) then		-- month initial month-day-year-range: month day, year – month day, year;  uses spaced endash&lt;br /&gt;
		month, day, year, month2, day2, anchor_year, year2=date_string:match(&amp;quot;(%a+) +(%d%d?), +(%d%d%d%d) – (%a+) +(%d%d?), +((%d%d%d%d)%a?)&amp;quot;);&lt;br /&gt;
		if tonumber(year2) &amp;lt;= tonumber(year) then return false; end												-- must be sequential years, left to right, earlier to later&lt;br /&gt;
		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&lt;br /&gt;
		month = get_month_number (month);																		-- for metadata&lt;br /&gt;
		month2 = get_month_number (month2);&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match(&amp;quot;^%a+ +[1-9]%d%d%d–%d%d%a?$&amp;quot;) then								-- special case Winter/Summer year-year (YYYY-YY); year separated with unspaced endash&lt;br /&gt;
		local century;&lt;br /&gt;
		month, year, century, anchor_year, year2=date_string:match(&amp;quot;(%a+) +((%d%d)%d%d)–((%d%d)%a?)&amp;quot;);&lt;br /&gt;
		if &amp;#039;Winter&amp;#039; ~= month and &amp;#039;Summer&amp;#039; ~= month then return false end;					-- &amp;#039;month&amp;#039; can only be Winter or Summer&lt;br /&gt;
		anchor_year=year..&amp;#039;–&amp;#039;..anchor_year;													-- assemble anchor_year from both years&lt;br /&gt;
		year2 = century..year2;																-- add the century to year2 for comparisons&lt;br /&gt;
		if 1 ~= tonumber(year2) - tonumber(year) then return false; end						-- must be sequential years, left to right, earlier to later&lt;br /&gt;
		if not is_valid_year(year2) then return false; end									-- no year farther in the future than next year&lt;br /&gt;
		month = get_season_number (month);&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match(&amp;quot;^%a+ +[1-9]%d%d%d–[1-9]%d%d%d%a?$&amp;quot;) then						-- special case Winter/Summer year-year; year separated with unspaced endash&lt;br /&gt;
		month, year, anchor_year, year2=date_string:match(&amp;quot;(%a+) +(%d%d%d%d)–((%d%d%d%d)%a?)&amp;quot;);&lt;br /&gt;
		if &amp;#039;Winter&amp;#039; ~= month and &amp;#039;Summer&amp;#039; ~= month then return false end;					-- &amp;#039;month&amp;#039; can only be Winter or Summer&lt;br /&gt;
		anchor_year=year..&amp;#039;–&amp;#039;..anchor_year;													-- assemble anchor_year from both years&lt;br /&gt;
		if 1 ~= tonumber(year2) - tonumber(year) then return false; end						-- must be sequential years, left to right, earlier to later&lt;br /&gt;
		if not is_valid_year(year2) then return false; end									-- no year farther in the future than next year&lt;br /&gt;
		month = get_season_number (month);													-- for metadata&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match(&amp;quot;^%a+ +[1-9]%d%d%d% – %a+ +[1-9]%d%d%d%a?$&amp;quot;) then				-- month/season year - month/season year; separated by spaced endash&lt;br /&gt;
		month, year, month2, anchor_year, year2=date_string:match(&amp;quot;(%a+) +(%d%d%d%d) – (%a+) +((%d%d%d%d)%a?)&amp;quot;);&lt;br /&gt;
		anchor_year=year..&amp;#039;–&amp;#039;..anchor_year;													-- assemble anchor_year from both years&lt;br /&gt;
		if tonumber(year) &amp;gt;= tonumber(year2) then return false; end							-- left to right, earlier to later, not the same&lt;br /&gt;
		if not is_valid_year(year2) then return false; end									-- no year farther in the future than next year&lt;br /&gt;
		if 0 ~= get_month_number(month) and 0 ~= get_month_number(month2) and is_valid_month_range_style(month, month2) then 	-- both must be month year, same month style&lt;br /&gt;
			month = get_month_number(month);&lt;br /&gt;
			month2 = get_month_number(month2);&lt;br /&gt;
		elseif 0 ~= get_season_number(month) and 0 ~= get_season_number(month2) then		-- both must be or season year, not mixed&lt;br /&gt;
			month = get_season_number(month);&lt;br /&gt;
			month2 = get_season_number(month2);&lt;br /&gt;
		else&lt;br /&gt;
			 return false;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match (&amp;quot;^%a+–%a+ +[1-9]%d%d%d%a?$&amp;quot;) then								-- month/season range year; months separated by endash &lt;br /&gt;
		month, month2, anchor_year, year=date_string:match (&amp;quot;(%a+)–(%a+)%s*((%d%d%d%d)%a?)&amp;quot;);&lt;br /&gt;
		if (not is_valid_month_season_range(month, month2)) or (not is_valid_year(year)) then return false; end&lt;br /&gt;
		if 0 ~= get_month_number(month) then									-- determined to be a valid range so just check this one to know if month or season&lt;br /&gt;
			month = get_month_number(month);&lt;br /&gt;
			month2 = get_month_number(month2);&lt;br /&gt;
		else&lt;br /&gt;
			month = get_season_number(month);&lt;br /&gt;
			month2 = get_season_number(month2);&lt;br /&gt;
		end&lt;br /&gt;
		year2=year;&lt;br /&gt;
		&lt;br /&gt;
	elseif date_string:match(&amp;quot;^%a+ +%d%d%d%d%a?$&amp;quot;) then							-- month/season year or proper-name year&lt;br /&gt;
		month, anchor_year, year=date_string:match(&amp;quot;(%a+)%s*((%d%d%d%d)%a?)&amp;quot;);&lt;br /&gt;
		if not is_valid_year(year) then return false; end&lt;br /&gt;
		if not is_valid_month_or_season (month) and 0 == is_proper_name (month) then return false; end&lt;br /&gt;
		if 0 ~= get_month_number(month) then									-- determined to be a valid range so just check this one to know if month or season&lt;br /&gt;
			month = get_month_number(month);&lt;br /&gt;
		elseif 0 ~= get_season_number(month) then&lt;br /&gt;
			month = get_season_number(month);&lt;br /&gt;
		else&lt;br /&gt;
			month = is_proper_name (month);										-- must be proper name; not supported in COinS&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match(&amp;quot;^[1-9]%d%d%d?–[1-9]%d%d%d?%a?$&amp;quot;) then				-- Year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999&lt;br /&gt;
		year, anchor_year, year2=date_string:match(&amp;quot;(%d%d%d%d?)–((%d%d%d%d?)%a?)&amp;quot;);&lt;br /&gt;
		anchor_year=year..&amp;#039;–&amp;#039;..anchor_year;										-- assemble anchor year from both years&lt;br /&gt;
		if tonumber(year) &amp;gt;= tonumber(year2) then return false; end				-- left to right, earlier to later, not the same&lt;br /&gt;
		if not is_valid_year(year2) then return false; end						-- no year farther in the future than next year&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match(&amp;quot;^[1-9]%d%d%d–%d%d%a?$&amp;quot;) then						-- Year range: YYYY–YY; separated by unspaced endash&lt;br /&gt;
		local century;&lt;br /&gt;
		year, century, anchor_year, year2=date_string:match(&amp;quot;((%d%d)%d%d)–((%d%d)%a?)&amp;quot;);&lt;br /&gt;
		anchor_year=year..&amp;#039;–&amp;#039;..anchor_year;										-- assemble anchor year from both years&lt;br /&gt;
		if 13 &amp;gt; tonumber(year2) then return false; end							-- don&amp;#039;t allow 2003-05 which might be May 2003&lt;br /&gt;
		year2 = century..year2;													-- add the century to year2 for comparisons&lt;br /&gt;
		if tonumber(year) &amp;gt;= tonumber(year2) then return false; end				-- left to right, earlier to later, not the same&lt;br /&gt;
		if not is_valid_year(year2) then return false; end						-- no year farther in the future than next year&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match(&amp;quot;^[1-9]%d%d%d?%a?$&amp;quot;) then							-- year; here accept either YYY or YYYY&lt;br /&gt;
		anchor_year, year=date_string:match(&amp;quot;((%d%d%d%d?)%a?)&amp;quot;);&lt;br /&gt;
		if false == is_valid_year(year) then&lt;br /&gt;
			return false;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
	else&lt;br /&gt;
		return false;											-- date format not one of the MOS:DATE approved formats&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local result=true;											-- check whole dates for validity; assume true because not all dates will go through this test&lt;br /&gt;
	if 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 == month2 and 0 == day2 then		-- YMD (simple whole date)&lt;br /&gt;
		result=is_valid_date(year,month,day);&lt;br /&gt;
&lt;br /&gt;
	elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 == month2 and 0 ~= day2 then	-- YMD-d (day range)&lt;br /&gt;
		result=is_valid_date(year,month,day);&lt;br /&gt;
		result=result and is_valid_date(year,month,day2);&lt;br /&gt;
&lt;br /&gt;
	elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 ~= month2 and 0 ~= day2 then	-- YMD-md (day month range)&lt;br /&gt;
		result=is_valid_date(year,month,day);&lt;br /&gt;
		result=result and is_valid_date(year,month2,day2);&lt;br /&gt;
&lt;br /&gt;
	elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 ~= year2 and 0 ~= month2 and 0 ~= day2 then	-- YMD-ymd (day month year range)&lt;br /&gt;
		result=is_valid_date(year,month,day);&lt;br /&gt;
		result=result and is_valid_date(year2,month2,day2);&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if false == result then return false; end&lt;br /&gt;
																-- if here, then date_string is valid; get coins_date from date_string (leave CITEREF disambiguator) ...&lt;br /&gt;
--	coins_date=date_string:match(&amp;quot;^(.+%d)%a?$&amp;quot;);				-- last character of valid disambiguatable date is always a digit&lt;br /&gt;
--	coins_date= mw.ustring.gsub(coins_date, &amp;quot;–&amp;quot;, &amp;quot;-&amp;quot; );			-- ... and replace any ndash with a hyphen&lt;br /&gt;
&lt;br /&gt;
	if nil ~= tCOinS_date then													-- this table only passed into this function when testing |date= parameter values&lt;br /&gt;
		make_COinS_date ({year=year, month=month, day=day, year2=year2, month2=month2, day2=day2}, tCOinS_date);	-- make an ISO 8601 date string for COinS&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return true, anchor_year;									-- format is good and date string represents a real date&lt;br /&gt;
--	return true, anchor_year, coins_date;						-- format is good and date string represents a real date&lt;br /&gt;
end	&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; D A T E S &amp;gt;--------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Cycle the date-holding parameters in passed table date_parameters_list through check_date() to check compliance with MOS:DATE. For all valid dates, check_date() returns&lt;br /&gt;
true. The |date= parameter test is unique, it is the only date holding parameter from which values for anchor_year (used in CITEREF identifiers) and COinS_date (used in&lt;br /&gt;
the COinS metadata) are derived.  The |date= parameter is the only date-holding parameter that is allowed to contain the no-date keywords &amp;quot;n.d.&amp;quot; or &amp;quot;nd&amp;quot; (without quotes).&lt;br /&gt;
&lt;br /&gt;
Unlike most error messages created in this module, only one error message is created by this function. Because all of the date holding parameters are processed serially,&lt;br /&gt;
a single error message is created as the dates are tested.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function dates(date_parameters_list, tCOinS_date)&lt;br /&gt;
	local anchor_year;		-- will return as nil if the date being tested is not |date=&lt;br /&gt;
	local COinS_date;		-- will return as nil if the date being tested is not |date=&lt;br /&gt;
	local error_message = &amp;quot;&amp;quot;;&lt;br /&gt;
--	local mismatch = 0;&lt;br /&gt;
	local good_date = false;&lt;br /&gt;
	&lt;br /&gt;
	for k, v in pairs(date_parameters_list) do										-- for each date-holding parameter in the list&lt;br /&gt;
		if is_set(v) then															-- if the parameter has a value&lt;br /&gt;
			if v:match(&amp;quot;^c%. [1-9]%d%d%d?%a?$&amp;quot;) then								-- special case for c. year or with or without CITEREF disambiguator - only |date= and |year=&lt;br /&gt;
				local year = v:match(&amp;quot;c%. ([1-9]%d%d%d?)%a?&amp;quot;);						-- get the year portion so it can be tested&lt;br /&gt;
				if &amp;#039;date&amp;#039;==k then&lt;br /&gt;
					anchor_year, COinS_date = v:match(&amp;quot;((c%. [1-9]%d%d%d?)%a?)&amp;quot;);	-- anchor year and COinS_date only from |date= parameter&lt;br /&gt;
					good_date = is_valid_year(year);&lt;br /&gt;
				elseif &amp;#039;year&amp;#039;==k then&lt;br /&gt;
					good_date = is_valid_year(year);&lt;br /&gt;
				end&lt;br /&gt;
			elseif &amp;#039;date&amp;#039;==k then													-- if the parameter is |date=&lt;br /&gt;
				if v:match(&amp;quot;^n%.d%.%a?&amp;quot;) then										-- if |date=n.d. with or without a CITEREF disambiguator&lt;br /&gt;
					good_date, anchor_year, COinS_date = true, v:match(&amp;quot;((n%.d%.)%a?)&amp;quot;);	--&amp;quot;n.d.&amp;quot;; no error when date parameter is set to no date&lt;br /&gt;
				elseif v:match(&amp;quot;^nd%a?$&amp;quot;) then										-- if |date=nd with or without a CITEREF disambiguator&lt;br /&gt;
					good_date, anchor_year, COinS_date = true, v:match(&amp;quot;((nd)%a?)&amp;quot;);	--&amp;quot;nd&amp;quot;;	no error when date parameter is set to no date&lt;br /&gt;
				else&lt;br /&gt;
					good_date, anchor_year, COinS_date = check_date (v, tCOinS_date);			-- go test the date&lt;br /&gt;
				end&lt;br /&gt;
			elseif &amp;#039;access-date&amp;#039;==k then												-- if the parameter is |date=&lt;br /&gt;
				good_date = check_date (v);											-- go test the date&lt;br /&gt;
				if true == good_date then											-- if the date is a valid date&lt;br /&gt;
					good_date = is_valid_accessdate (v);							-- is Wikipedia start date &amp;lt; accessdate &amp;lt; tomorrow&amp;#039;s date?&lt;br /&gt;
				end&lt;br /&gt;
			else																	-- any other date-holding parameter&lt;br /&gt;
				good_date = check_date (v);											-- go test the date&lt;br /&gt;
			end&lt;br /&gt;
			if false==good_date then												-- assemble one error message so we don&amp;#039;t add the tracking category multiple times&lt;br /&gt;
				if is_set(error_message) then										-- once we&amp;#039;ve added the first portion of the error message ...&lt;br /&gt;
					error_message=error_message .. &amp;quot;, &amp;quot;;							-- ... add a comma space separator&lt;br /&gt;
				end&lt;br /&gt;
				error_message=error_message .. &amp;quot;&amp;amp;#124;&amp;quot; .. k .. &amp;quot;=&amp;quot;;				-- add the failed parameter&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
--	return anchor_year, COinS_date, error_message, mismatch;					-- and done&lt;br /&gt;
	return anchor_year, error_message;											-- and done&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; Y E A R _ D A T E _ C H E C K &amp;gt;------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Compare the value provided in |year= with the year value(s) provided in |date=.  This function returns a numeric value:&lt;br /&gt;
	0 - year value does not match the year value in date&lt;br /&gt;
	1 - (default) year value matches the year value in date or one of the year values when date contains two years&lt;br /&gt;
	2 - year value matches the year value in date when date is in the form YYYY-MM-DD and year is disambiguated (|year=YYYYx)&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function year_date_check (year_string, date_string)&lt;br /&gt;
	local year;&lt;br /&gt;
	local date1;&lt;br /&gt;
	local date2;&lt;br /&gt;
	local result = 1;															-- result of the test; assume that the test passes&lt;br /&gt;
	&lt;br /&gt;
	year = year_string:match (&amp;#039;(%d%d%d%d?)&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
	if date_string:match (&amp;#039;%d%d%d%d%-%d%d%-%d%d&amp;#039;) and year_string:match (&amp;#039;%d%d%d%d%a&amp;#039;) then	--special case where date and year required YYYY-MM-DD and YYYYx&lt;br /&gt;
		date1 = date_string:match (&amp;#039;(%d%d%d%d)&amp;#039;);&lt;br /&gt;
		year = year_string:match (&amp;#039;(%d%d%d%d)&amp;#039;);&lt;br /&gt;
		if year ~= date1 then&lt;br /&gt;
			result = 0;															-- years don&amp;#039;t match&lt;br /&gt;
		else&lt;br /&gt;
			result = 2;															-- years match; but because disambiguated, don&amp;#039;t add to maint cat&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
	elseif date_string:match (&amp;quot;%d%d%d%d?.-%d%d%d%d?&amp;quot;) then						-- any of the standard formats of date with two three- or four-digit years&lt;br /&gt;
		date1, date2 = date_string:match (&amp;quot;(%d%d%d%d?).-(%d%d%d%d?)&amp;quot;);&lt;br /&gt;
		if year ~= date1 and year ~= date2 then&lt;br /&gt;
			result = 0;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match (&amp;quot;%d%d%d%d[%s%-–]+%d%d&amp;quot;) then						-- YYYY-YY date ranges&lt;br /&gt;
		local century;&lt;br /&gt;
		date1, century, date2 = date_string:match (&amp;quot;((%d%d)%d%d)[%s%-–]+(%d%d)&amp;quot;);&lt;br /&gt;
		date2 = century..date2;													-- convert YY to YYYY&lt;br /&gt;
		if year ~= date1 and year ~= date2 then&lt;br /&gt;
			result = 0;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
	elseif date_string:match (&amp;quot;%d%d%d%d?&amp;quot;) then									-- any of the standard formats of date with one year&lt;br /&gt;
		date1 = date_string:match (&amp;quot;(%d%d%d%d?)&amp;quot;);&lt;br /&gt;
		if year ~= date1 then&lt;br /&gt;
			result = 0;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return result;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return {dates = dates, year_date_check = year_date_check}						-- return exported functions&lt;/div&gt;</summary>
		<author><name>أسيل سيوف</name></author>
	</entry>
</feed>