封建社会是什么意思| 守旧是什么意思| 子宫痒是什么原因| 老鸨是什么意思| 用什么泡脚减肥最快| 什么叫肠化| 为什么阴天紫外线更强| 肺炎吃什么水果| 抖m什么意思| 低压低吃什么药| 小米长什么样| 圣诞节礼物什么时候送| 什么是七情六欲| 蒲公英泡水喝有什么功效| 星字属于五行属什么| 脾胃不好喝什么茶| 81年属什么生肖| 妈宝男是什么意思| 小猫什么时候断奶| 额头冒痘是什么原因| 全血铅测定是什么意思| 吃榴莲对身体有什么好处| 天启是什么意思| 什么是肺大泡| 十八罗汉是什么意思| 什么情况| 严重脱发是什么原因| 梭织棉是什么面料| 射手座的幸运色是什么| 鼻子两侧毛孔粗大是什么原因造成的| 前列腺增生伴钙化是什么意思| 肺在五行中属什么| 高危妊娠是什么意思啊| 蚊子不喜欢什么血型| 血清铁蛋白高说明什么| 扶苏是什么意思| 不复相见什么意思| 为什么声音老是嘶哑| 消失是什么意思| 所言极是是什么意思| 闰月要给父母买什么| 掏耳朵咳嗽是什么原因| 今日是什么生肖日| fashion什么意思| 芝士是什么东西| 吃什么可以控制血糖| 蒲公英的约定表达什么| 什么什么大名| 油蜡皮是什么皮| 做梦梦到男朋友出轨了是什么意思| 1.13是什么星座| 床垫选什么材质的好| 海绵体是什么| 四十年是什么婚| 血脂高是什么原因| 势利是什么意思| 手腕血管疼是什么原因| 日后好相见的前一句是什么| 钧鉴是什么意思| 口蘑不能和什么一起吃| 什么是文科| 什么字属金| 10.21是什么星座| 月亮是什么颜色| 6月25是什么星座| 鼻子出汗是什么原因| 窦性心律不齐是什么意思| 沁是什么意思| 克罗心是什么档次| 什么是腹泻| 脚麻木是什么病的前兆| 宫颈糜烂用什么药| 9月8号是什么星座| 晚上猫叫有什么预兆| 脱发缺少什么维生素| 间歇性跛行是什么意思| cdc是什么意思| 早上八点到九点属于什么时辰| hs医学上是什么意思| 梦见做手术是什么意思| 漂亮的什么| 婷婷玉立什么意思| 威慑力是什么意思| 什么得什么词语| 芒果有什么好处| 水指什么生肖| 1981属什么| 俄罗斯的国花是什么花| 印模是什么意思| 小孩嗓子疼吃什么药| 什么硬币最值钱| 乙肝五项245阳性是什么意思| 5月31号是什么星座| 做肠镜要挂什么科| 扁桃体有什么作用| 侃侃而谈是什么意思| kid什么意思| 徐州二院全名叫什么| 甲低有什么症状表现| 身上长疣是什么原因| 左眼跳是什么预兆| 郁金香长什么样子| 属猪和什么属相相冲| 脸颊红是什么原因| 动脉血是什么颜色| 什么的朝霞| 人为什么要喝水| 什么的面目| 胆黄素高是怎么回事有什么危害| 尿道感染吃什么消炎药| 海啸是什么| 肚子胀气是什么原因引起的| arf是什么意思| 总是出汗是什么原因| 天麻泡水喝有什么功效| 甲流是什么病| 尿胆原高是什么原因| 裹腹是什么意思| 买碗有什么讲究| 属兔与什么属相相克| tct是什么意思| 异常心电图是什么意思| 凋谢是什么意思| 芥末是什么味道| 眼睛白色部分叫什么| 21年是什么生肖年| 什么魂什么魄| 烤冷面是什么材料做的| 在什么什么前面| 痛经打什么针止痛| 看破红尘是什么意思| 来例假不能吃什么东西| 金银花泡水喝有什么功效| 怕冷的女人是什么原因| 祭司是干什么的| mlb是什么牌子| 感觉不到饿是什么原因| 巴戟天为什么要抽芯| 苏打水什么味道| 懒觉什么意思| 左眼皮老是跳是什么原因| 窈窕淑女是什么生肖| 新疆人为什么长得像外国人| 姜子牙为什么没有封神| 羊肉不能和什么水果一起吃| 梦见自己家被盗有什么预兆| 右手发麻是什么病的前兆| hds是什么意思| 甲沟炎吃什么药| 手肘发黑是什么原因| 正月二十一是什么星座| 魔芋是什么| 96122是什么电话| 荞麦茶有什么功效| 金字旁目字读什么| 直接胆红素高是什么病| 经常掏耳朵有什么危害| 胃看什么科室| 头里面有肿瘤有什么症状| 嘴唇上长水泡是什么原因| 脑卒中是什么病| 静夜思是什么季节| 监狱长是什么级别| 大学团委书记什么级别| 皮肤瘙痒用什么药| 丁丁历险记的狗是什么品种| 空调一级能效什么意思| 什么是唐氏儿| 离子水是什么水| 嘴唇有点发黑是什么原因引起的| 9月3号什么日子| 纹身有什么讲究和忌讳| 大便硬是什么原因| 鲜字五行属什么| 上火喝什么茶效果最好| 2b是什么意思| 黑枸杞泡水喝有什么好处| 颜艺是什么意思| btc是什么货币| 消炎药都有什么| 什么是碱性磷酸酶高怎么回事| 什么是tct检查| 复方是什么意思| 肝功七项查的是什么| 夏天适合种什么植物| 同归于尽是什么意思| 水军是什么意思| 掉头发吃什么恢复最快| 肝火旺盛喝什么茶| 大便感觉拉不干净什么原因| 报告是什么意思| 老年人补什么钙效果最好| 小腹胀痛什么原因女性| 厌氧菌是什么意思| 什么材料| 肠系膜淋巴结肿大吃什么药| 什么眼霜比较好用| 水痘可以吃什么| 醋纤是什么面料| 什么嫩芽| 怀孕第一个月有什么特征| 胬肉是什么| 什么是阻生牙| 备孕需要做些什么准备| 颈椎生理曲度变直是什么意思| 3.4是什么星座| 吕字五行属什么| 隽字五行属什么| 属兔与什么属相相克| 拉稀吃什么药| 丙肝吃什么药效果好| 港澳通行证签注是什么意思| 低密度脂蛋白高有什么症状| 胳膊肘往外拐是什么意思| 破屋坏垣适合干什么| 牙龈肿痛什么原因| 一失足成千古恨是什么意思| 仓鼠不能吃什么| 沙中土命什么意思| hpv阴性是什么意思| 茜草别名又叫什么| 杜甫自号什么| 安眠药有什么副作用| 山竹树长什么样子图片| 不变应万变是什么意思| 心口痛挂什么科| 钠氯偏低是什么原因| 什么是创业板股票| 高血压吃什么食物最好| 阴历六月十八是什么日子| 什么是螨虫型痘痘图片| 饕餮长什么样| 什么是性质| 收官什么意思| 咬肌疼是什么原因| 心血管科是看什么病| 十九畏是什么意思| 副书记是什么级别| 转移什么意思| emoji是什么意思| 女人右眼跳是什么意思| 雨五行属什么| 气短是什么意思| 什么叫阳性率| 胎儿左心室强光点是什么意思| 尖锐湿疣的症状是什么| 焦虑症是什么原因引起的| 华胥是什么意思| 网球肘用什么膏药效果好| 五月十九日是什么星座| 男人额头凹陷预示什么| 乙肝表面抗原是什么意思| 黑色素沉淀是什么原因引起的| as是什么| 宝宝睡觉出汗是什么原因| 肾囊性灶是什么意思| 身上长瘊子是什么原因| 顾问是什么意思| 嘴麻是什么原因引起的| 妈祖属什么生肖| 丁字是什么意思| 小狗能吃什么水果| 铁树开花是什么意思| 乳房痛是什么原因| 百度Jump to content

脚后跟疼是什么病

Permanently protected module
From Meta, a Wikimedia project coordination wiki
Module documentation
百度   粉煤灰变废为宝原本是件好事,但接下来又出现了新问题。


This module contains routines that support the Citation Style 1 and Citation Style 2 date formats for citations on Wikipedia. In particular, this module contains a suite of functions that validate date formats and content for the variety of date-holding parameters associated with cs1|2 citations.


These files comprise the module support for cs1|2 citation templates:

cs2 modules
  live sandbox description
sysop Module:Citation/CS1 Module:Citation/CS1/sandbox Rendering and support functions
Module:Citation/CS1/Configuration Module:Citation/CS1/Configuration/sandbox Translation tables; error and identifier handlers
Module:Citation/CS1/Whitelist Module:Citation/CS1/Whitelist/sandbox List of active, deprecated, and obsolete CS1 parameters
Module:Citation/CS1/Date validation Module:Citation/CS1/Date validation/sandbox Date format validation functions
auto confirmed Module:Citation/CS1/Suggestions Module:Citation/CS1/Suggestions/sandbox List that maps common erroneous parameter names to valid parameter names

local p = {}

--[[--------------------------< I S _ V A L I D _ A C C E S S D A T E >----------------------------------------

returns true if:
	Wikipedia start date <= accessdate < today + 2 days

Wikipedia start date is 2025-08-06T00:00:00 UTC which is 979516800 seconds after 2025-08-06T00:00:00 UTC (the start of Unix time)
accessdate is the date provided in |accessdate= at time 00:00:00 UTC
today is the current date at time 00:00:00 UTC plus 48 hours
	if today is 2025-08-06T00:00:00 then
		adding 24 hours gives 2025-08-06T00:00:00 – one second more than today
		adding 24 hours gives 2025-08-06T00:00:00 – one second more than tomorrow

]]

local function is_valid_accessdate (accessdate)
	local lang = mw.getContentLanguage();
	local good1, good2;
	local access_ts, tomorrow_ts;												-- to hold unix time stamps representing the dates
		
	good1, access_ts = pcall( lang.formatDate, lang, 'U', accessdate );			-- convert accessdate value to unix timesatmp 
	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
		access_ts = tonumber (access_ts);										-- convert to numbers for the comparison
		tomorrow_ts = tonumber (tomorrow_ts);
	else
		return false;															-- one or both failed to convert to unix time stamp
	end
	
	if 979516800 <= access_ts and access_ts < tomorrow_ts then					-- Wikipedia start date <= accessdate < tomorrow's date
		return true;
	else
		return false;															-- accessdate out of range
	end
end

--[[--------------------------< G E T _ M O N T H _ N U M B E R >----------------------------------------------

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

]]

local function get_month_number (month)
local long_months = {['January']=1, ['February']=2, ['March']=3, ['April']=4, ['May']=5, ['June']=6, ['July']=7, ['August']=8, ['September']=9, ['October']=10, ['November']=11, ['December']=12};
local short_months = {['Jan']=1, ['Feb']=2, ['Mar']=3, ['Apr']=4, ['May']=5, ['Jun']=6, ['Jul']=7, ['Aug']=8, ['Sep']=9, ['Oct']=10, ['Nov']=11, ['Dec']=12};
local temp;
	temp=long_months[month];
	if temp then return temp; end				-- if month is the long-form name
	temp=short_months[month];
	if temp then return temp; end				-- if month is the short-form name
	return 0;									-- misspelled, improper case, or not a month name
end

--[[--------------------------< G E T _ S E A S O N _ N U M B E R >--------------------------------------------

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

]]

local function get_season_number (season)
local season_list = {['Winter']=1, ['Spring']=2, ['Summer']=3, ['Fall']=4, ['Autumn']=4}
local temp;
	temp=season_list[season];
	if temp then return temp; end				-- if season is a valid name return its number
	return 0;									-- misspelled, improper case, or not a season name
end

--[[--------------------------< I S _ P R O P E R _ N A M E >--------------------------------------------------

returns a non-zero number if date contains a recognized proper name.  Capitalization and spelling must be correct.

]]

local function is_proper_name (name)
local name_list = {['Christmas']=1}
local temp;
	temp=name_list[name];
	if temp then return temp; end				-- if name is a valid name return its number
	return 0;									-- misspelled, improper case, or not a proper name
end

--[[--------------------------< I S _ V A L I D _ M O N T H _ O R _ S E A S O N >------------------------------

--returns true if month or season is valid (properly spelled, capitalized, abbreviated)

]]

local function is_valid_month_or_season (month_season)
	if 0 == get_month_number (month_season) then		-- if month text isn't one of the twelve months, might be a season
		if 0 == get_season_number (month_season) then	-- not a month, is it a season?
			return false;								-- return false not a month or one of the five seasons
		end
	end
	return true;
end


--[[--------------------------< I S _ V A L I D _ Y E A R >----------------------------------------------------

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.

]]

local function is_valid_year(year)
	if not is_set(year_limit) then
		year_limit = tonumber(os.date("%Y"))+1;			-- global variable so we only have to fetch it once
	end
	return tonumber(year) <= year_limit;				-- false if year is in the future more than one year
end

--[[
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.

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.
Where the two calendars overlap (1582 to approximately 1923) dates are assumed to be Gregorian.
]]
local function is_valid_date (year, month, day)
local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
local month_length;
	if not is_valid_year(year) then	-- no farther into the future than next year
		return false;
	end
	
	if (2==month) then							-- if February
		month_length = 28;						-- then 28 days unless
		if 1582 > tonumber(year) then			-- Julian calendar
			if 0==(year%4) then
				month_length = 29;
			end
		else									-- Gregorian calendar
			if (0==(year%4) and (0~=(year%100) or 0==(year%400))) then	-- is a leap year?
				month_length = 29;				-- if leap year then 29 days in February
			end
		end
	else
		month_length=days_in_month[month];
	end

	if tonumber (day) > month_length then
		return false;
	end
	return true;
end

--[[--------------------------< I S _ V A L I D _ M O N T H _ R A N G E _ S T Y L E >--------------------------

Months in a range are expected to have the same style: Jan–Mar or October–December but not February–Mar or Jul–August. 
There is a special test for May because it can be either short or long form.

Returns true when style for both months is the same

]]

local function is_valid_month_range_style (month1, month2)
local len1 = month1:len();
local len2 = month2:len();
	if len1 == len2 then
		return true;															-- both months are short form so return true
	elseif 'May' == month1 or 'May'== month2 then
		return true;															-- both months are long form so return true
	elseif 3 == len1 or 3 == len2 then
		return false;															-- months are mixed form so return false
	else
		return true;															-- both months are long form so return true
	end
end


--[[--------------------------< I S _ V A L I D _ M O N T H _ S E A S O N _ R A N G E >------------------------

Check a pair of months or seasons to see if both are valid members of a month or season pair.

Month pairs are expected to be left to right, earliest to latest in time.

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, ...,
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.

]]

local function is_valid_month_season_range(range_start, range_end)
	local range_start_number = get_month_number (range_start);
	
	if 0 == range_start_number then								-- is this a month range?
		local range_start_number = get_season_number (range_start);		-- not a month; is it a season? get start season number
		local range_end_number = get_season_number (range_end);			-- get end season number

		if 0 ~= range_start_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 season and follows start season; else false
			end
			if 4 == range_start_number and 1 == range_end_number then	-- special case when range is Fall-Winter or Autumn-Winter
				return true;
			end
		end
		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
	end

	local 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?
		if is_valid_month_range_style (range_start, range_end) then				-- do months have the same style?
			return true;														-- proper order and same style
		end
	end
	return false;												-- range_start month number is greater than or equal to range end number; or range end isn't a month
end

--[[--------------------------< C H E C K _ D A T E >----------------------------------------------------------

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.
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
character abbreviations, and seasons must be spelled correctly. Future years beyond next year are not allowed.

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
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.

Inputs:
	date_string - date string from date-holding parameters (date, year, accessdate, embargo, archivedate, etc.)

Returns:
	false if date string is not a real date; else
	true, anchor_year, COinS_date
		anchor_year can be used in CITEREF anchors
		COinS_date is date_string without anchor_year disambiguator if any
]]
local function check_date (date_string)
	local year;			-- assume that year2, months, and days are not used;
	local year2=0;		-- second year in a year range
	local month=0;
	local month2=0;		-- second month in a month range
	local day=0;
	local day2=0;		-- second day in a day range
	local anchor_year;
	local coins_date;

	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)");
		month=tonumber(month);
		if 12 < month or 1 > month or 1583 > tonumber(year) then return false; end			-- month number not valid or not Gregorian calendar
		anchor_year = year;

	elseif date_string:match("^%a+ +[1-9]%d?, +[1-9]%d%d%d%a?$") then						-- month-initial: month day, year
		month, day, anchor_year, year=string.match(date_string, "(%a+)%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 date_string:match("^%a+ +[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=string.match(date_string, "(%a+) +(%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);
		if 0 == month then return false; end												-- return false if month text isn't one of the twelve months

	elseif date_string:match("^[1-9]%d? +%a+ +[1-9]%d%d%d%a?$") then						-- day-initial: day month year
		day, month, anchor_year, year=string.match(date_string, "(%d%d*)%s*(%a+)%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 date_string:match("^[1-9]%d?–[1-9]%d? +%a+ +[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=string.match(date_string, "(%d%d?)–(%d%d?) +(%a+) +((%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);
		if 0 == month then return false; end												-- return false if month text isn't one of the twelve months

	elseif date_string:match("^[1-9]%d? +%a+ – [1-9]%d? +%a+ +[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=date_string:match("(%d%d?) +(%a+) – (%d%d?) +(%a+) +((%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);
		month2 = get_month_number (month2);

	elseif date_string:match("^%a+ +[1-9]%d? – %a+ +[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=date_string:match("(%a+) +(%d%d?) – (%a+) +(%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);
		month2 = get_month_number (month2);

	elseif date_string:match("^[1-9]%d? +%a+ +[1-9]%d%d%d – [1-9]%d? +%a+ +[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=date_string:match("(%d%d?) +(%a+) +(%d%d%d%d?) – (%d%d?) +(%a+) +((%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
		month = get_month_number (month);
		month2 = get_month_number (month2);

	elseif date_string:match("^%a+ +[1-9]%d?, +[1-9]%d%d%d – %a+ +[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=date_string:match("(%a+) +(%d%d?), +(%d%d%d%d) – (%a+) +(%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
		month = get_month_number (month);
		month2 = get_month_number (month2);

	elseif date_string:match("^%a+ +[1-9]%d%d%d–%d%d%a?$") then								-- special case Winter/Summer year-year (YYYY-YY); year separated with unspaced endash
		if nil == date_string:match("^Winter") and nil == date_string:match("^Summer") then return false end;	-- 'month' can only be Winter or Summer
		local century;
		year, century, anchor_year, year2=date_string:match("%a+ +((%d%d)%d%d)–((%d%d)%a?)");
		anchor_year=year..'–'..anchor_year;													-- assemble anchor_year from both years
		year2 = century..year2;																-- add the century to year2 for comparisons
		if 1 ~= tonumber(year2) - tonumber(year) then return false; end						-- must be sequential years, left to right, earlier to later
		if not is_valid_year(year2) then return false; end									-- no year farther in the future than next year

	elseif date_string:match("^%a+ +[1-9]%d%d%d–[1-9]%d%d%d%a?$") then						-- special case Winter/Summer year-year; year separated with unspaced endash
		if nil == date_string:match("^Winter") and nil == date_string:match("^Summer") then return false end;	-- 'month' can only be Winter or Summer
		year, anchor_year, year2=date_string:match("%a+ +(%d%d%d%d)–((%d%d%d%d)%a?)");
		anchor_year=year..'–'..anchor_year;													-- assemble anchor_year from both years
		if 1 ~= tonumber(year2) - tonumber(year) then return false; end						-- must be sequential years, left to right, earlier to later
		if not is_valid_year(year2) then return false; end									-- no year farther in the future than next year

	elseif date_string:match("^%a+ +[1-9]%d%d%d% – %a+ +[1-9]%d%d%d%a?$") then				-- month/season year - month/season year; separated by spaced endash
		month, year, month2, anchor_year, year2=date_string:match("(%a+) +(%d%d%d%d) – (%a+) +((%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
		if not is_valid_year(year2) then return false; end									-- no year farther in the future than next year
		if not((0 ~= get_month_number(month) and 0 ~= get_month_number(month2) and is_valid_month_range_style(month, month2)) or 	-- both must be month year, same month style
			(0 ~= get_season_number(month) and 0 ~= get_season_number(month2))) then return false; end								-- or season year, not mixed

	elseif date_string:match ("^%a+–%a+ +[1-9]%d%d%d%a?$") then								-- month/season range year; months separated by endash 
		month, month2, anchor_year, year=date_string:match ("(%a+)–(%a+)%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
		
	elseif date_string:match("^%a+ +%d%d%d%d%a?$") then							-- month/season year or proper-name year
		month, anchor_year, year=date_string:match("(%a+)%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

	elseif date_string:match("^[1-9]%d%d%d?–[1-9]%d%d%d?%a?$") then				-- Year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999
		year, anchor_year, year2=date_string:match("(%d%d%d%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
		if not is_valid_year(year2) then return false; end						-- no year farther in the future than next year

	elseif date_string:match("^[1-9]%d%d%d–%d%d%a?$") then						-- Year range: YYYY–YY; separated by unspaced endash
		local century;
		year, century, anchor_year, year2=date_string:match("((%d%d)%d%d)–((%d%d)%a?)");
		anchor_year=year..'–'..anchor_year;										-- assemble anchor year from both years
		if 13 > tonumber(year2) then return false; end							-- don't allow 2003-05 which might be May 2003
		year2 = century..year2;													-- add the century to year2 for comparisons
		if tonumber(year) >= tonumber(year2) then return false; end				-- left to right, earlier to later, not the same
		if not is_valid_year(year2) then return false; end						-- no year farther in the future than next year

	elseif date_string:match("^[1-9]%d%d%d?%a?$") then							-- year; here accept either YYY or YYYY
		anchor_year, year=date_string:match("((%d%d%d%d?)%a?)");
		if false == is_valid_year(year) then
			return false;
		end

	else
		return false;											-- date format not one of the MOS:DATE approved formats
	end

	local result=true;											-- check whole dates for validity; assume true because not all dates will go through this test
	if 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 == month2 and 0 == day2 then		-- YMD (simple whole date)
		result=is_valid_date(year,month,day);

	elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 == month2 and 0 ~= day2 then	-- YMD-d (day range)
		result=is_valid_date(year,month,day);
		result=result and is_valid_date(year,month,day2);

	elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 ~= month2 and 0 ~= day2 then	-- YMD-md (day month range)
		result=is_valid_date(year,month,day);
		result=result and is_valid_date(year,month2,day2);

	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)
		result=is_valid_date(year,month,day);
		result=result and is_valid_date(year2,month2,day2);
	end
	
	if false == result then return false; end
																-- if here, then date_string is valid; get coins_date from date_string (leave CITEREF disambiguator) ...
	coins_date=date_string:match("^(.+%d)%a?$");				-- last character of valid disambiguatable date is always a digit
	coins_date= mw.ustring.gsub(coins_date, "–", "-" );			-- ... and replace any ndash with a hyphen
	
	return true, anchor_year, coins_date;						-- format is good and date string represents a real date
end	

--[[--------------------------< D A T E S >--------------------------------------------------------------------

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
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
the COinS metadata) are derived.  The |date= parameter is the only date-holding parameter that is allowed to contain the no-date keywords "n.d." or "nd" (without quotes).

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,
a single error message is created as the dates are tested.

]]

--function p.dates(date_parameters_list)
local function dates(date_parameters_list)
	local anchor_year;		-- will return as nil if the date being tested is not |date=
	local COinS_date;		-- will return as nil if the date being tested is not |date=
	local error_message = "";
	local mismatch = 0;
	local good_date = false;
	
	for k, v in pairs(date_parameters_list) do										-- for each date-holding parameter in the list
		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=
				local year = v:match("c%. ([1-9]%d%d%d?)%a?");						-- get the year portion so it can be tested
				if 'date'==k then
					anchor_year, COinS_date = v:match("((c%. [1-9]%d%d%d?)%a?)");	-- anchor year and COinS_date only from |date= parameter
					good_date = is_valid_year(year);
				elseif 'year'==k then
					good_date = is_valid_year(year);
				end
			elseif 'date'==k then													-- if the parameter is |date=
				if v:match("^n%.d%.%a?") then										-- if |date=n.d. with or without a CITEREF disambiguator
					good_date, anchor_year, COinS_date = true, v:match("((n%.d%.)%a?)");	--"n.d."; no error when date parameter is set to no date
				elseif v:match("^nd%a?$") then										-- if |date=nd with or without a CITEREF disambiguator
					good_date, anchor_year, COinS_date = true, v:match("((nd)%a?)");	--"nd";	no error when date parameter is set to no date
				else
					good_date, anchor_year, COinS_date = check_date (v);			-- go test the date
				end
			elseif 'access-date'==k then												-- if the parameter is |date=
				good_date = check_date (v);											-- go test the date
				if true == good_date then											-- if the date is a valid date
					good_date = is_valid_accessdate (v);							-- is Wikipedia start date < accessdate < tomorrow's date?
				end
			else																	-- any other date-holding parameter
				good_date = check_date (v);											-- go test the date
			end
			if false==good_date then												-- assemble one error message so we don't add the tracking category multiple times
				if is_set(error_message) then										-- once we've added the first portion of the error message ...
					error_message=error_message .. ", ";							-- ... add a comma space separator
				end
				error_message=error_message .. "&#124;" .. k .. "=";				-- add the failed parameter
			end
		end
	end
	return anchor_year, COinS_date, error_message, mismatch;					-- and done
end

--[[--------------------------< Y E A R _ D A T E _ C H E C K >------------------------------------------------

Compare the value provided in |year= with the year value(s) provided in |date=.  This function returns a numeric value:
	0 - year value does not match the year value in date
	1 - (default) year value matches the year value in date or one of the year values when date contains two years
	2 - year value matches the year value in date when date is in the form YYYY-MM-DD and year is disambiguated (|year=YYYYx)

]]

local function year_date_check (year_string, date_string)
	local year;
	local date1;
	local date2;
	local result = 1;															-- result of the test; assume that the test passes
	
	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
		date1 = date_string:match ('(%d%d%d%d)');
		year = year_string:match ('(%d%d%d%d)');
		if year ~= date1 then
			result = 0;															-- years don't match
		else
			result = 2;															-- years match; but because disambiguated, don't add to maint cat
		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
		date1, date2 = date_string:match ("(%d%d%d%d?).-(%d%d%d%d?)");
		if year ~= date1 and year ~= date2 then
			result = 0;
		end

	elseif date_string:match ("%d%d%d%d[%s%-–]+%d%d") then						-- YYYY-YY date ranges
		local century;
		date1, century, date2 = date_string:match ("((%d%d)%d%d)[%s%-–]+(%d%d)");
		date2 = century..date2;													-- convert YY to YYYY
		if year ~= date1 and year ~= date2 then
			result = 0;
		end

	elseif date_string:match ("%d%d%d%d?") then									-- any of the standard formats of date with one year
		date1 = date_string:match ("(%d%d%d%d?)");
		if year ~= date1 then
			result = 0;
		end
	end
	return result;
end

return {dates = dates, year_date_check = year_date_check}						-- return exported functions
农历十月初八是什么星座 地主之谊是什么意思 野鸡吃什么食物 上梁山是什么意思 沵是什么意思
asmr是什么 结巴是什么原因引起的 全身发冷是什么原因 牛鞭是牛的什么部位 查hpv挂什么科
冉冉是什么意思 背影杀是什么意思 孕妇尿路感染吃什么药 什么不能带上高铁 形婚是什么意思啊
paris什么牌子 巨细胞病毒是什么 一什么湖水 七月一是什么星座 什么是肛瘘
fa什么意思hcv8jop7ns8r.cn 梅毒病有什么症状hcv9jop3ns2r.cn 海龟汤是什么gangsutong.com ein是什么牌子beikeqingting.com 网络维护是做什么的hcv8jop2ns4r.cn
频繁放屁是什么原因hcv8jop4ns1r.cn 回不到我们的从前是什么歌hcv9jop8ns0r.cn 山竹有什么功效和作用hcv8jop0ns8r.cn 漂洋过海是什么生肖hcv9jop5ns2r.cn 艾滋病是什么症状hcv9jop4ns8r.cn
什么是干燥综合症hcv7jop6ns3r.cn 去医院看头发挂什么科hcv8jop2ns3r.cn 容易打嗝是什么原因hcv8jop6ns5r.cn 大美是什么意思hcv8jop4ns0r.cn 孕妇吃鸽子蛋对胎儿有什么好处hcv8jop0ns6r.cn
狒狒是什么动物hcv7jop6ns8r.cn 保持器是什么hcv8jop9ns4r.cn 步长是什么意思wuhaiwuya.com 权志龙的团队叫什么hcv8jop1ns4r.cn 前列腺实质回声欠均匀什么意思shenchushe.com
百度