<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://www.wikiw.cn/index.php?action=history&amp;feed=atom&amp;title=%E6%A8%A1%E5%9D%97%3AAge</id>
	<title>模块:Age - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://www.wikiw.cn/index.php?action=history&amp;feed=atom&amp;title=%E6%A8%A1%E5%9D%97%3AAge"/>
	<link rel="alternate" type="text/html" href="https://www.wikiw.cn/index.php?title=%E6%A8%A1%E5%9D%97:Age&amp;action=history"/>
	<updated>2026-04-08T15:01:11Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://www.wikiw.cn/index.php?title=%E6%A8%A1%E5%9D%97:Age&amp;diff=357&amp;oldid=prev</id>
		<title>Admin：​导入1个版本</title>
		<link rel="alternate" type="text/html" href="https://www.wikiw.cn/index.php?title=%E6%A8%A1%E5%9D%97:Age&amp;diff=357&amp;oldid=prev"/>
		<updated>2025-06-20T17:02:25Z</updated>

		<summary type="html">&lt;p&gt;导入1个版本&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2025年6月21日 (六) 01:02的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;zh-Hans-CN&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;（没有差异）&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://www.wikiw.cn/index.php?title=%E6%A8%A1%E5%9D%97:Age&amp;diff=356&amp;oldid=prev</id>
		<title>wikiw&gt;Ericliu1912：​依據編輯請求更新頁面</title>
		<link rel="alternate" type="text/html" href="https://www.wikiw.cn/index.php?title=%E6%A8%A1%E5%9D%97:Age&amp;diff=356&amp;oldid=prev"/>
		<updated>2024-04-04T08:07:46Z</updated>

		<summary type="html">&lt;p&gt;依據編輯請求更新頁面&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- Implement various &amp;quot;age of&amp;quot; and other date-related templates.&lt;br /&gt;
&lt;br /&gt;
local _Date, _currentDate&lt;br /&gt;
local function getExports(frame)&lt;br /&gt;
	-- Return objects exported from the date module or its sandbox.&lt;br /&gt;
	if not _Date then&lt;br /&gt;
		local sandbox = frame:getTitle():find(&amp;#039;sandbox&amp;#039;, 1, true) and &amp;#039;/sandbox&amp;#039; or &amp;#039;&amp;#039;&lt;br /&gt;
		local datemod = require(&amp;#039;Module:Date&amp;#039; .. sandbox)&lt;br /&gt;
		_Date = datemod._Date&lt;br /&gt;
		_currentDate = datemod._current&lt;br /&gt;
	end&lt;br /&gt;
	return _Date, _currentDate&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local Collection  -- a table to hold items&lt;br /&gt;
Collection = {&lt;br /&gt;
	add = function (self, item)&lt;br /&gt;
		if item ~= nil then&lt;br /&gt;
			self.n = self.n + 1&lt;br /&gt;
			self[self.n] = item&lt;br /&gt;
		end&lt;br /&gt;
	end,&lt;br /&gt;
	join = function (self, sep)&lt;br /&gt;
		return table.concat(self, sep)&lt;br /&gt;
	end,&lt;br /&gt;
	remove = function (self, pos)&lt;br /&gt;
		if self.n &amp;gt; 0 and (pos == nil or (0 &amp;lt; pos and pos &amp;lt;= self.n)) then&lt;br /&gt;
			self.n = self.n - 1&lt;br /&gt;
			return table.remove(self, pos)&lt;br /&gt;
		end&lt;br /&gt;
	end,&lt;br /&gt;
	sort = function (self, comp)&lt;br /&gt;
		table.sort(self, comp)&lt;br /&gt;
	end,&lt;br /&gt;
	new = function ()&lt;br /&gt;
		return setmetatable({n = 0}, Collection)&lt;br /&gt;
	end&lt;br /&gt;
}&lt;br /&gt;
Collection.__index = Collection&lt;br /&gt;
&lt;br /&gt;
local function stripToNil(text)&lt;br /&gt;
	-- If text is a string, return its trimmed content, or nil if empty.&lt;br /&gt;
	-- Otherwise return text (which may, for example, be nil).&lt;br /&gt;
	if type(text) == &amp;#039;string&amp;#039; then&lt;br /&gt;
		text = text:match(&amp;#039;(%S.-)%s*$&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local yes = require(&amp;#039;Module:Yesno&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local function message(msg, id)&lt;br /&gt;
	-- Return formatted message text for an error or warning.&lt;br /&gt;
	local categories = {&lt;br /&gt;
		error = &amp;#039;[[Category:Age模块错误]]&amp;#039;,&lt;br /&gt;
		warning = &amp;#039;[[Category:Age模块错误]]&amp;#039;,  -- same as error until determine whether &amp;#039;Age warning&amp;#039; would be worthwhile&lt;br /&gt;
	}&lt;br /&gt;
	local a, b, category&lt;br /&gt;
	if id == &amp;#039;warning&amp;#039; then&lt;br /&gt;
		a = &amp;#039;&amp;lt;sup&amp;gt;[&amp;lt;i&amp;gt;&amp;#039;&lt;br /&gt;
		b = &amp;#039;&amp;lt;/i&amp;gt;]&amp;lt;/sup&amp;gt;&amp;#039;&lt;br /&gt;
	else&lt;br /&gt;
		a = &amp;#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;错误：&amp;#039;&lt;br /&gt;
		b = &amp;#039;&amp;lt;/strong&amp;gt;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	if mw.title.getCurrentTitle():inNamespaces(0) then&lt;br /&gt;
		-- Category only in namespaces: 0=article.&lt;br /&gt;
		category = categories[id or &amp;#039;error&amp;#039;]&lt;br /&gt;
	end&lt;br /&gt;
	return&lt;br /&gt;
		a ..&lt;br /&gt;
		mw.text.nowiki(msg) ..&lt;br /&gt;
		b ..&lt;br /&gt;
		(category or &amp;#039;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function formatNumber(number)&lt;br /&gt;
	-- Return the given number formatted with commas as group separators,&lt;br /&gt;
	-- given that the number is an integer.&lt;br /&gt;
	local numstr = tostring(number)&lt;br /&gt;
	local length = #numstr&lt;br /&gt;
	local places = Collection.new()&lt;br /&gt;
	local pos = 0&lt;br /&gt;
	repeat&lt;br /&gt;
		places:add(pos)&lt;br /&gt;
		pos = pos + 3&lt;br /&gt;
	until pos &amp;gt;= length&lt;br /&gt;
	places:add(length)&lt;br /&gt;
	local groups = Collection.new()&lt;br /&gt;
	for i = places.n, 2, -1 do&lt;br /&gt;
		local p1 = length - places[i] + 1&lt;br /&gt;
		local p2 = length - places[i - 1]&lt;br /&gt;
		groups:add(numstr:sub(p1, p2))&lt;br /&gt;
	end&lt;br /&gt;
	return groups:join(&amp;#039;,&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function spellNumber(number, options, i)&lt;br /&gt;
	-- Return result of spelling number, or&lt;br /&gt;
	-- return number (as a string) if cannot spell it.&lt;br /&gt;
	-- i == 1 for the first number which can optionally start with an uppercase letter.&lt;br /&gt;
	number = tostring(number)&lt;br /&gt;
	return require(&amp;#039;Module:ConvertNumeric&amp;#039;).spell_number(&lt;br /&gt;
		number,&lt;br /&gt;
		nil,                       -- fraction numerator&lt;br /&gt;
		nil,                       -- fraction denominator&lt;br /&gt;
		i == 1 and options.upper,  -- true: &amp;#039;One&amp;#039; instead of &amp;#039;one&amp;#039;&lt;br /&gt;
		not options.us,            -- true: use &amp;#039;and&amp;#039; between tens/ones etc&lt;br /&gt;
		options.adj,               -- true: hyphenated&lt;br /&gt;
		options.ordinal            -- true: &amp;#039;first&amp;#039; instead of &amp;#039;one&amp;#039;&lt;br /&gt;
	) or number&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeSort(value, sortable)&lt;br /&gt;
	-- Return a sort key if requested.&lt;br /&gt;
	-- Assume value is a valid number which has not overflowed.&lt;br /&gt;
	if sortable == &amp;#039;sortable_table&amp;#039; or sortable == &amp;#039;sortable_on&amp;#039; or sortable == &amp;#039;sortable_debug&amp;#039; then&lt;br /&gt;
		local sortkey&lt;br /&gt;
		if value == 0 then&lt;br /&gt;
			sortkey = &amp;#039;5000000000000000000&amp;#039;&lt;br /&gt;
		else&lt;br /&gt;
			local mag = math.floor(math.log10(math.abs(value)) + 1e-14)&lt;br /&gt;
			local prefix&lt;br /&gt;
			if value &amp;gt; 0 then&lt;br /&gt;
				prefix = 7000 + mag&lt;br /&gt;
			else&lt;br /&gt;
				prefix = 2999 - mag&lt;br /&gt;
				value = value + 10^(mag+1)&lt;br /&gt;
			end&lt;br /&gt;
			sortkey = string.format(&amp;#039;%d&amp;#039;, prefix) .. string.format(&amp;#039;%015.0f&amp;#039;, math.floor(value * 10^(14-mag)))&lt;br /&gt;
		end&lt;br /&gt;
		local lhs, rhs&lt;br /&gt;
		if sortable == &amp;#039;sortable_table&amp;#039; then&lt;br /&gt;
			lhs = &amp;#039;data-sort-value=&amp;quot;&amp;#039;&lt;br /&gt;
			rhs = &amp;#039;&amp;quot;|&amp;#039;&lt;br /&gt;
		else&lt;br /&gt;
			lhs = sortable == &amp;#039;sortable_debug&amp;#039; and&lt;br /&gt;
				&amp;#039;&amp;lt;span style=&amp;quot;border:1px solid;display:inline;&amp;quot; class=&amp;quot;sortkey&amp;quot;&amp;gt;&amp;#039; or&lt;br /&gt;
				&amp;#039;&amp;lt;span style=&amp;quot;display:none&amp;quot; class=&amp;quot;sortkey&amp;quot;&amp;gt;&amp;#039;&lt;br /&gt;
			rhs = &amp;#039;♠&amp;lt;/span&amp;gt;&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
		return lhs .. sortkey .. rhs&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local translateParameters = {&lt;br /&gt;
	abbr = {&lt;br /&gt;
		off = &amp;#039;abbr_off&amp;#039;,&lt;br /&gt;
		on = &amp;#039;abbr_on&amp;#039;,&lt;br /&gt;
	},&lt;br /&gt;
	disp = {&lt;br /&gt;
		age = &amp;#039;disp_age&amp;#039;,&lt;br /&gt;
		raw = &amp;#039;disp_raw&amp;#039;,&lt;br /&gt;
	},&lt;br /&gt;
	format = {&lt;br /&gt;
		raw = &amp;#039;format_raw&amp;#039;,&lt;br /&gt;
		commas = &amp;#039;format_commas&amp;#039;,&lt;br /&gt;
	},&lt;br /&gt;
	round = {&lt;br /&gt;
		on = &amp;#039;on&amp;#039;,&lt;br /&gt;
		yes = &amp;#039;on&amp;#039;,&lt;br /&gt;
		months = &amp;#039;ym&amp;#039;,&lt;br /&gt;
		weeks = &amp;#039;ymw&amp;#039;,&lt;br /&gt;
		days = &amp;#039;ymd&amp;#039;,&lt;br /&gt;
		hours = &amp;#039;ymdh&amp;#039;,&lt;br /&gt;
	},&lt;br /&gt;
	sep = {&lt;br /&gt;
		comma = &amp;#039;sep_comma&amp;#039;,&lt;br /&gt;
		[&amp;#039;,&amp;#039;] = &amp;#039;sep_comma&amp;#039;,&lt;br /&gt;
		serialcomma = &amp;#039;sep_serialcomma&amp;#039;,&lt;br /&gt;
		space = &amp;#039;sep_space&amp;#039;,&lt;br /&gt;
	},&lt;br /&gt;
	show = {&lt;br /&gt;
		hide = { id = &amp;#039;hide&amp;#039; },&lt;br /&gt;
		y = { &amp;#039;y&amp;#039;, id = &amp;#039;y&amp;#039; },&lt;br /&gt;
		ym = { &amp;#039;y&amp;#039;, &amp;#039;m&amp;#039;, id = &amp;#039;ym&amp;#039; },&lt;br /&gt;
		ymd = { &amp;#039;y&amp;#039;, &amp;#039;m&amp;#039;, &amp;#039;d&amp;#039;, id = &amp;#039;ymd&amp;#039; },&lt;br /&gt;
		ymw = { &amp;#039;y&amp;#039;, &amp;#039;m&amp;#039;, &amp;#039;w&amp;#039;, id = &amp;#039;ymw&amp;#039; },&lt;br /&gt;
		ymwd = { &amp;#039;y&amp;#039;, &amp;#039;m&amp;#039;, &amp;#039;w&amp;#039;, &amp;#039;d&amp;#039;, id = &amp;#039;ymwd&amp;#039; },&lt;br /&gt;
		yd = { &amp;#039;y&amp;#039;, &amp;#039;d&amp;#039;, id = &amp;#039;yd&amp;#039;, keepZero = true },&lt;br /&gt;
		m = { &amp;#039;m&amp;#039;, id = &amp;#039;m&amp;#039; },&lt;br /&gt;
		md = { &amp;#039;m&amp;#039;, &amp;#039;d&amp;#039;, id = &amp;#039;md&amp;#039; },&lt;br /&gt;
		w = { &amp;#039;w&amp;#039;, id = &amp;#039;w&amp;#039; },&lt;br /&gt;
		wd = { &amp;#039;w&amp;#039;, &amp;#039;d&amp;#039;, id = &amp;#039;wd&amp;#039; },&lt;br /&gt;
		h = { &amp;#039;H&amp;#039;, id = &amp;#039;h&amp;#039; },&lt;br /&gt;
		hm = { &amp;#039;H&amp;#039;, &amp;#039;M&amp;#039;, id = &amp;#039;hm&amp;#039; },&lt;br /&gt;
		hms = { &amp;#039;H&amp;#039;, &amp;#039;M&amp;#039;, &amp;#039;S&amp;#039;, id = &amp;#039;hms&amp;#039; },&lt;br /&gt;
		d = { &amp;#039;d&amp;#039;, id = &amp;#039;d&amp;#039; },&lt;br /&gt;
		dh = { &amp;#039;d&amp;#039;, &amp;#039;H&amp;#039;, id = &amp;#039;dh&amp;#039; },&lt;br /&gt;
		dhm = { &amp;#039;d&amp;#039;, &amp;#039;H&amp;#039;, &amp;#039;M&amp;#039;, id = &amp;#039;dhm&amp;#039; },&lt;br /&gt;
		dhms = { &amp;#039;d&amp;#039;, &amp;#039;H&amp;#039;, &amp;#039;M&amp;#039;, &amp;#039;S&amp;#039;, id = &amp;#039;dhms&amp;#039; },&lt;br /&gt;
		ymdh = { &amp;#039;y&amp;#039;, &amp;#039;m&amp;#039;, &amp;#039;d&amp;#039;, &amp;#039;H&amp;#039;, id = &amp;#039;ymdh&amp;#039; },&lt;br /&gt;
		ymdhm = { &amp;#039;y&amp;#039;, &amp;#039;m&amp;#039;, &amp;#039;d&amp;#039;, &amp;#039;H&amp;#039;, &amp;#039;M&amp;#039;, id = &amp;#039;ymdhm&amp;#039; },&lt;br /&gt;
		ymwdh = { &amp;#039;y&amp;#039;, &amp;#039;m&amp;#039;, &amp;#039;w&amp;#039;, &amp;#039;d&amp;#039;, &amp;#039;H&amp;#039;, id = &amp;#039;ymwdh&amp;#039; },&lt;br /&gt;
		ymwdhm = { &amp;#039;y&amp;#039;, &amp;#039;m&amp;#039;, &amp;#039;w&amp;#039;, &amp;#039;d&amp;#039;, &amp;#039;H&amp;#039;, &amp;#039;M&amp;#039;, id = &amp;#039;ymwdhm&amp;#039; },&lt;br /&gt;
	},&lt;br /&gt;
	sortable = {&lt;br /&gt;
		off = false,&lt;br /&gt;
		on = &amp;#039;sortable_on&amp;#039;,&lt;br /&gt;
		table = &amp;#039;sortable_table&amp;#039;,&lt;br /&gt;
		debug = &amp;#039;sortable_debug&amp;#039;,&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local spellOptions = {&lt;br /&gt;
	cardinal = {},&lt;br /&gt;
	Cardinal = { upper = true },&lt;br /&gt;
	cardinal_us = { us = true },&lt;br /&gt;
	Cardinal_us = { us = true, upper = true },&lt;br /&gt;
	ordinal = { ordinal = true },&lt;br /&gt;
	Ordinal = { ordinal = true, upper = true },&lt;br /&gt;
	ordinal_us = { ordinal = true, us = true },&lt;br /&gt;
	Ordinal_us = { ordinal = true, us = true, upper = true },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function dateExtract(frame)&lt;br /&gt;
	-- Return part of a date after performing an optional operation.&lt;br /&gt;
	local Date = getExports(frame)&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	local parms = {}&lt;br /&gt;
	for i, v in ipairs(args) do&lt;br /&gt;
		parms[i] = v&lt;br /&gt;
	end&lt;br /&gt;
	if yes(args.fix) then&lt;br /&gt;
		table.insert(parms, &amp;#039;fix&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	if yes(args.partial) then&lt;br /&gt;
		table.insert(parms, &amp;#039;partial&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	local show = stripToNil(args.show) or &amp;#039;dmy&amp;#039;&lt;br /&gt;
	local date = Date(unpack(parms))&lt;br /&gt;
	if not date then&lt;br /&gt;
		if show == &amp;#039;format&amp;#039; then&lt;br /&gt;
			return &amp;#039;error&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
		return message(&amp;#039;需要有效的日期&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	local add = stripToNil(args.add)&lt;br /&gt;
	if add then&lt;br /&gt;
		for item in add:gmatch(&amp;#039;%S+&amp;#039;) do&lt;br /&gt;
			date = date + item&lt;br /&gt;
			if not date then&lt;br /&gt;
				return message(&amp;#039;无法添加“&amp;#039; .. item .. &amp;#039;”&amp;#039;)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local prefix, result&lt;br /&gt;
	local sortable = translateParameters.sortable[args.sortable]&lt;br /&gt;
	if sortable then&lt;br /&gt;
		local value = (date.partial and date.partial.first or date).jdz&lt;br /&gt;
		prefix = makeSort(value, sortable)&lt;br /&gt;
	end&lt;br /&gt;
	if show ~= &amp;#039;hide&amp;#039; then&lt;br /&gt;
		result = date[show]&lt;br /&gt;
		if result == nil then&lt;br /&gt;
			result = date:text(show)&lt;br /&gt;
		elseif type(result) == &amp;#039;boolean&amp;#039; then&lt;br /&gt;
			result = result and &amp;#039;1&amp;#039; or &amp;#039;0&amp;#039;&lt;br /&gt;
		else&lt;br /&gt;
			result = tostring(result)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return (prefix or &amp;#039;&amp;#039;) .. (result or &amp;#039;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function rangeJoin(range)&lt;br /&gt;
	-- Return text to be used between a range of ages.&lt;br /&gt;
	return range == &amp;#039;dash&amp;#039; and &amp;#039;—&amp;#039; or &amp;#039;或&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeText(values, components, names, options, noUpper)&lt;br /&gt;
	-- Return wikitext representing an age or duration.&lt;br /&gt;
	local text = Collection.new()&lt;br /&gt;
	local count = #values&lt;br /&gt;
	local sep = names.sep or &amp;#039;&amp;#039;&lt;br /&gt;
	for i, v in ipairs(values) do&lt;br /&gt;
		-- v is a number (say 4 for 4 years), or a table ({4,5} for 4 or 5 years).&lt;br /&gt;
		local islist = type(v) == &amp;#039;table&amp;#039;&lt;br /&gt;
		if (islist or v &amp;gt; 0) or (text.n == 0 and i == count) or (text.n &amp;gt; 0 and components.keepZero) then&lt;br /&gt;
			local fmt, vstr&lt;br /&gt;
			if options.spell then&lt;br /&gt;
				fmt = function(number)&lt;br /&gt;
					return spellNumber(number, options.spell, noUpper or i)&lt;br /&gt;
				end&lt;br /&gt;
			elseif i == 1 and options.format == &amp;#039;format_commas&amp;#039; then&lt;br /&gt;
				-- Numbers after the first should be small and not need formatting.&lt;br /&gt;
				fmt = formatNumber&lt;br /&gt;
			else&lt;br /&gt;
				fmt = tostring&lt;br /&gt;
			end&lt;br /&gt;
			if islist then&lt;br /&gt;
				vstr = fmt(v[1]) .. rangeJoin(options.range)&lt;br /&gt;
				noUpper = true&lt;br /&gt;
				vstr = vstr .. fmt(v[2])&lt;br /&gt;
			else&lt;br /&gt;
				vstr = fmt(v)&lt;br /&gt;
			end&lt;br /&gt;
			local name = names[components[i]]&lt;br /&gt;
			if name then&lt;br /&gt;
				local plural = names.plural&lt;br /&gt;
				if not plural or (islist and v[2] or v) == 1 then&lt;br /&gt;
					plural = &amp;#039;&amp;#039;&lt;br /&gt;
				end&lt;br /&gt;
				text:add(vstr .. sep .. name .. plural)&lt;br /&gt;
			else&lt;br /&gt;
				text:add(vstr)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local first, last&lt;br /&gt;
	-- hh mm ss&lt;br /&gt;
	if options.join == &amp;#039;sep_space&amp;#039; then&lt;br /&gt;
		first = &amp;#039; &amp;#039;&lt;br /&gt;
		last = &amp;#039; &amp;#039;&lt;br /&gt;
	-- hh时，mm分，ss秒&lt;br /&gt;
	elseif options.join == &amp;#039;sep_comma&amp;#039; then&lt;br /&gt;
		first = &amp;#039;，&amp;#039;&lt;br /&gt;
		last = &amp;#039;，&amp;#039;&lt;br /&gt;
	-- hh时，mm分又ss秒&lt;br /&gt;
	elseif options.join == &amp;#039;sep_serialcomma&amp;#039; then&lt;br /&gt;
		first = &amp;#039;，&amp;#039;&lt;br /&gt;
		last = text.n &amp;gt; 2 and (names.y == &amp;#039;年&amp;#039; and &amp;#039;又&amp;#039; or &amp;#039;零&amp;#039;) or &amp;#039;，&amp;#039;&lt;br /&gt;
	-- hh时mm分ss秒&lt;br /&gt;
	elseif options.join == &amp;#039;sep_none&amp;#039; then&lt;br /&gt;
		first = &amp;#039;&amp;#039;&lt;br /&gt;
		last = &amp;#039;&amp;#039;&lt;br /&gt;
	-- hh时mm分又ss秒&lt;br /&gt;
	else  -- &amp;#039;sep_serial&amp;#039;&lt;br /&gt;
		first = &amp;#039;&amp;#039;&lt;br /&gt;
		last = text.n &amp;gt; 2 and (names.y == &amp;#039;年&amp;#039; and &amp;#039;又&amp;#039; or &amp;#039;零&amp;#039;) or &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	for i, v in ipairs(text) do&lt;br /&gt;
		if i &amp;lt; text.n then&lt;br /&gt;
			text[i] = v .. (i + 1 &amp;lt; text.n and first or last)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local sign = &amp;#039;&amp;#039;&lt;br /&gt;
	if options.isnegative then&lt;br /&gt;
		-- Do not display negative zero.&lt;br /&gt;
		if text.n &amp;gt; 1 or (text.n == 1 and text[1]:sub(1, 1) ~= &amp;#039;0&amp;#039; ) then&lt;br /&gt;
			if options.format == &amp;#039;format_raw&amp;#039; then&lt;br /&gt;
				sign = &amp;#039;-&amp;#039;  -- plain hyphen so result can be used in a calculation&lt;br /&gt;
			else&lt;br /&gt;
				sign = &amp;#039;−&amp;#039;  -- Unicode U+2212 MINUS SIGN&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return&lt;br /&gt;
		(options.prefix or &amp;#039;&amp;#039;) ..&lt;br /&gt;
		(options.extra or &amp;#039;&amp;#039;) ..&lt;br /&gt;
		sign ..&lt;br /&gt;
		text:join() ..&lt;br /&gt;
		(options.suffix or &amp;#039;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function dateDifference(parms)&lt;br /&gt;
	-- Return a formatted date difference using the given parameters&lt;br /&gt;
	-- which have been validated.&lt;br /&gt;
	local names = {&lt;br /&gt;
		abbr_off = {&lt;br /&gt;
			plural = &amp;#039;&amp;#039;,&lt;br /&gt;
			sep = &amp;#039;&amp;#039;,&lt;br /&gt;
			y = &amp;#039;年&amp;#039;,&lt;br /&gt;
			m = &amp;#039;个月&amp;#039;,&lt;br /&gt;
			w = &amp;#039;周&amp;#039;,&lt;br /&gt;
			d = &amp;#039;天&amp;#039;,&lt;br /&gt;
			H = &amp;#039;小时&amp;#039;,&lt;br /&gt;
			M = &amp;#039;分&amp;#039;,&lt;br /&gt;
			S = &amp;#039;秒&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		abbr_on = {&lt;br /&gt;
			y = &amp;#039;y&amp;#039;,&lt;br /&gt;
			m = &amp;#039;m&amp;#039;,&lt;br /&gt;
			w = &amp;#039;w&amp;#039;,&lt;br /&gt;
			d = &amp;#039;d&amp;#039;,&lt;br /&gt;
			H = &amp;#039;h&amp;#039;,&lt;br /&gt;
			M = &amp;#039;m&amp;#039;,&lt;br /&gt;
			S = &amp;#039;s&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		abbr_age = {&lt;br /&gt;
			plural = &amp;#039;&amp;#039;,&lt;br /&gt;
			sep = &amp;#039;&amp;#039;,&lt;br /&gt;
			y = &amp;#039;岁&amp;#039;,&lt;br /&gt;
			m = &amp;#039;个月&amp;#039;,&lt;br /&gt;
			w = &amp;#039;周&amp;#039;,&lt;br /&gt;
			d = &amp;#039;天&amp;#039;,&lt;br /&gt;
			H = &amp;#039;小时&amp;#039;,&lt;br /&gt;
			M = &amp;#039;分&amp;#039;,&lt;br /&gt;
			S = &amp;#039;秒&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		abbr_raw = {},&lt;br /&gt;
	}&lt;br /&gt;
	local diff = parms.diff  -- must be a valid date difference&lt;br /&gt;
	local show = parms.show  -- may be nil; default is set below&lt;br /&gt;
	local abbr = parms.abbr or &amp;#039;abbr_off&amp;#039;&lt;br /&gt;
	local defaultJoin  -- 中文应该全为nil&lt;br /&gt;
	if abbr ~= &amp;#039;abbr_off&amp;#039; then&lt;br /&gt;
		defaultJoin = nil&lt;br /&gt;
	end&lt;br /&gt;
	if not show then&lt;br /&gt;
		show = &amp;#039;ymd&amp;#039;&lt;br /&gt;
		if parms.disp == &amp;#039;disp_age&amp;#039; then&lt;br /&gt;
			if diff.years &amp;lt; 3 then&lt;br /&gt;
				defaultJoin = nil&lt;br /&gt;
				if diff.years &amp;gt;= 1 then&lt;br /&gt;
					show = &amp;#039;ym&amp;#039;&lt;br /&gt;
				else&lt;br /&gt;
					show = &amp;#039;md&amp;#039;&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				show = &amp;#039;y&amp;#039;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if type(show) ~= &amp;#039;table&amp;#039; then&lt;br /&gt;
		show = translateParameters.show[show]&lt;br /&gt;
	end&lt;br /&gt;
	if parms.disp == &amp;#039;disp_raw&amp;#039; then&lt;br /&gt;
		defaultJoin = &amp;#039;sep_space&amp;#039;&lt;br /&gt;
		abbr = &amp;#039;abbr_raw&amp;#039;&lt;br /&gt;
	elseif parms.wantSc then&lt;br /&gt;
		defaultJoin = &amp;#039;sep_serialcomma&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	local diffOptions = {&lt;br /&gt;
		round = parms.round,&lt;br /&gt;
		duration = parms.wantDuration,&lt;br /&gt;
		range = parms.range and true or nil,&lt;br /&gt;
	}&lt;br /&gt;
	local prefix&lt;br /&gt;
	if parms.sortable then&lt;br /&gt;
		local value = diff.age_days + (parms.wantDuration and 1 or 0)  -- days and fraction of a day&lt;br /&gt;
		if diff.isnegative then&lt;br /&gt;
			value = -value&lt;br /&gt;
		end&lt;br /&gt;
		prefix = makeSort(value, parms.sortable)&lt;br /&gt;
	end&lt;br /&gt;
	local textOptions = {&lt;br /&gt;
		prefix = prefix,&lt;br /&gt;
		suffix = parms.suffix,  -- not currently used&lt;br /&gt;
		extra = parms.extra,&lt;br /&gt;
		format = parms.format,&lt;br /&gt;
		join = parms.sep or defaultJoin,&lt;br /&gt;
		isnegative = diff.isnegative,&lt;br /&gt;
		range = parms.range,&lt;br /&gt;
		spell = parms.spell,&lt;br /&gt;
	}&lt;br /&gt;
	if show.id == &amp;#039;hide&amp;#039; then&lt;br /&gt;
		return prefix or &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	local values = { diff:age(show.id, diffOptions) }&lt;br /&gt;
	if values[1] then&lt;br /&gt;
		return makeText(values, show, names[abbr], textOptions)&lt;br /&gt;
	end&lt;br /&gt;
	if diff.partial then&lt;br /&gt;
		-- Handle a more complex range such as&lt;br /&gt;
		-- {{age_yd|20 Dec 2001|2003|range=yes}} → 1 year, 12 days or 2 years, 11 days&lt;br /&gt;
		local opt = {&lt;br /&gt;
			format = textOptions.format,&lt;br /&gt;
			join = textOptions.join,&lt;br /&gt;
			isnegative = textOptions.isnegative,&lt;br /&gt;
			spell = textOptions.spell,&lt;br /&gt;
		}&lt;br /&gt;
		return&lt;br /&gt;
			(textOptions.prefix or &amp;#039;&amp;#039;) ..&lt;br /&gt;
			makeText({ diff.partial.mindiff:age(show.id, diffOptions) }, show, names[abbr], opt) ..&lt;br /&gt;
			rangeJoin(textOptions.range) ..&lt;br /&gt;
			makeText({ diff.partial.maxdiff:age(show.id, diffOptions) }, show, names[abbr], opt, true) ..&lt;br /&gt;
			(textOptions.suffix or &amp;#039;&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	return message(&amp;#039;此处不支持参数show=&amp;#039; .. show.id)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getDates(frame, getopt)&lt;br /&gt;
	-- Parse template parameters and return one of:&lt;br /&gt;
	-- * date         (a date table, if single)&lt;br /&gt;
	-- * date1, date2 (two date tables, if not single)&lt;br /&gt;
	-- * text         (a string error message)&lt;br /&gt;
	-- A missing date is optionally replaced with the current date.&lt;br /&gt;
	-- If wantMixture is true, a missing date component is replaced&lt;br /&gt;
	-- from the current date, so can get a bizarre mixture of&lt;br /&gt;
	-- specified/current y/m/d as has been done by some &amp;quot;age&amp;quot; templates.&lt;br /&gt;
	-- Some results may be placed in table getopt.&lt;br /&gt;
	local Date, currentDate = getExports(frame)&lt;br /&gt;
	getopt = getopt or {}&lt;br /&gt;
	local function flagCurrent(text)&lt;br /&gt;
		-- This allows the calling template to detect if the current date has been used,&lt;br /&gt;
		-- that is, whether both dates have been entered in a template expecting two.&lt;br /&gt;
		-- For example, an infobox may want the age when an event occurred, not the current age.&lt;br /&gt;
		-- Don&amp;#039;t bother detecting if wantMixture is used because not needed and it is a poor option.&lt;br /&gt;
		if not text then&lt;br /&gt;
			text = &amp;#039;currentdate&amp;#039;&lt;br /&gt;
			if getopt.flag == &amp;#039;usesCurrent&amp;#039; then&lt;br /&gt;
				getopt.usesCurrent = true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return text&lt;br /&gt;
	end&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	local fields = {}&lt;br /&gt;
	local isNamed = args.year or args.year1 or args.year2 or&lt;br /&gt;
		args.month or args.month1 or args.month2 or&lt;br /&gt;
		args.day or args.day1 or args.day2&lt;br /&gt;
	if isNamed then&lt;br /&gt;
		fields[1] = args.year1 or args.year&lt;br /&gt;
		fields[2] = args.month1 or args.month&lt;br /&gt;
		fields[3] = args.day1 or args.day&lt;br /&gt;
		fields[4] = args.year2&lt;br /&gt;
		fields[5] = args.month2&lt;br /&gt;
		fields[6] = args.day2&lt;br /&gt;
	else&lt;br /&gt;
		for i = 1, 6 do&lt;br /&gt;
			fields[i] = args[i]&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local imax = 0&lt;br /&gt;
	for i = 1, 6 do&lt;br /&gt;
		fields[i] = stripToNil(fields[i])&lt;br /&gt;
		if fields[i] then&lt;br /&gt;
			imax = i&lt;br /&gt;
		end&lt;br /&gt;
		if getopt.omitZero and i % 3 ~= 1 then  -- omit zero months and days as unknown values but keep year 0 which is 1 BCE&lt;br /&gt;
			if tonumber(fields[i]) == 0 then&lt;br /&gt;
				fields[i] = nil&lt;br /&gt;
				getopt.partial = true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local fix = getopt.fix and &amp;#039;fix&amp;#039; or &amp;#039;&amp;#039;&lt;br /&gt;
	local noDefault = imax == 0 and getopt.noMissing&lt;br /&gt;
	local partialText = getopt.partial and &amp;#039;partial&amp;#039; or &amp;#039;&amp;#039;&lt;br /&gt;
	local dates = {}&lt;br /&gt;
	if isNamed or imax &amp;gt;= 3 then&lt;br /&gt;
		local nrDates = getopt.single and 1 or 2&lt;br /&gt;
		if getopt.wantMixture then&lt;br /&gt;
			-- Cannot be partial since empty fields are set from current.&lt;br /&gt;
			local components = { &amp;#039;year&amp;#039;, &amp;#039;month&amp;#039;, &amp;#039;day&amp;#039; }&lt;br /&gt;
			for i = 1, nrDates * 3 do&lt;br /&gt;
				fields[i] = fields[i] or currentDate[components[i &amp;gt; 3 and i - 3 or i]]&lt;br /&gt;
			end&lt;br /&gt;
			for i = 1, nrDates do&lt;br /&gt;
				local index = i == 1 and 1 or 4&lt;br /&gt;
				dates[i] = Date(fields[index], fields[index+1], fields[index+2])&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- If partial dates are allowed, accept&lt;br /&gt;
			--     year only, or&lt;br /&gt;
			--     year and month only&lt;br /&gt;
			-- Do not accept year and day without a month because that makes no sense&lt;br /&gt;
			-- (and because, for example, Date(&amp;#039;partial&amp;#039;, 2001, nil, 12) sets day = nil, not 12).&lt;br /&gt;
			for i = 1, nrDates do&lt;br /&gt;
				local index = i == 1 and 1 or 4&lt;br /&gt;
				local y, m, d = fields[index], fields[index+1], fields[index+2]&lt;br /&gt;
				if (getopt.partial and y and (m or not d)) or (y and m and d) then&lt;br /&gt;
					dates[i] = Date(fix, partialText, y, m, d)&lt;br /&gt;
				elseif not y and not m and not d and not noDefault then&lt;br /&gt;
					dates[i] = Date(flagCurrent())&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	elseif not noDefault then&lt;br /&gt;
		getopt.textdates = true  -- have parsed each date from a single text field&lt;br /&gt;
		dates[1] = Date(fix, partialText, flagCurrent(fields[1]))&lt;br /&gt;
		if not getopt.single then&lt;br /&gt;
			dates[2] = Date(fix, partialText, flagCurrent(fields[2]))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if not dates[1] then&lt;br /&gt;
		return message(&amp;#039;需要有效的年月日&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	if getopt.single then&lt;br /&gt;
		return dates[1]&lt;br /&gt;
	end&lt;br /&gt;
	if not dates[2] then&lt;br /&gt;
		return message(&amp;#039;第二个日期应该是年月日&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	return dates[1], dates[2]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function ageGeneric(frame)&lt;br /&gt;
	-- Return the result required by the specified template.&lt;br /&gt;
	-- Can use sortable=x where x = on/table/off/debug in any supported template.&lt;br /&gt;
	-- Some templates default to sortable=on but can be overridden.&lt;br /&gt;
	local name = frame.args.template&lt;br /&gt;
	if not name then&lt;br /&gt;
		return message(&amp;#039;调用它的模板必须有“|template=x”参数，其中x是所需的操作&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	local specs = {&lt;br /&gt;
		-- 重点！切勿随意更改！&lt;br /&gt;
		age_days = {                -- {{age in days}}&lt;br /&gt;
			show = &amp;#039;d&amp;#039;,&lt;br /&gt;
			disp = &amp;#039;disp_raw&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		age_days_nts = {            -- {{age in days nts}}&lt;br /&gt;
			show = &amp;#039;d&amp;#039;,&lt;br /&gt;
			disp = &amp;#039;disp_raw&amp;#039;,&lt;br /&gt;
			format = &amp;#039;format_commas&amp;#039;,&lt;br /&gt;
			sortable = &amp;#039;on&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		duration_days = {           -- {{duration in days}}&lt;br /&gt;
			show = &amp;#039;d&amp;#039;,&lt;br /&gt;
			disp = &amp;#039;disp_raw&amp;#039;,&lt;br /&gt;
			duration = true,&lt;br /&gt;
		},&lt;br /&gt;
		duration_days_nts = {       -- {{duration in days nts}}&lt;br /&gt;
			show = &amp;#039;d&amp;#039;,&lt;br /&gt;
			disp = &amp;#039;disp_raw&amp;#039;,&lt;br /&gt;
			format = &amp;#039;format_commas&amp;#039;,&lt;br /&gt;
			sortable = &amp;#039;on&amp;#039;,&lt;br /&gt;
			duration = true,&lt;br /&gt;
		},&lt;br /&gt;
		age_full_years = {          -- {{age}}&lt;br /&gt;
			show = &amp;#039;y&amp;#039;,&lt;br /&gt;
			abbr = &amp;#039;abbr_raw&amp;#039;,&lt;br /&gt;
			flag = &amp;#039;usesCurrent&amp;#039;,&lt;br /&gt;
			omitZero = true,&lt;br /&gt;
			range = &amp;#039;no&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		age_full_years_nts = {      -- {{age nts}}&lt;br /&gt;
			show = &amp;#039;y&amp;#039;,&lt;br /&gt;
			abbr = &amp;#039;abbr_raw&amp;#039;,&lt;br /&gt;
			format = &amp;#039;format_commas&amp;#039;,&lt;br /&gt;
			sortable = &amp;#039;on&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		age_in_years = {            -- {{age in years}}&lt;br /&gt;
			show = &amp;#039;y&amp;#039;,&lt;br /&gt;
			abbr = &amp;#039;abbr_raw&amp;#039;,&lt;br /&gt;
			negative = &amp;#039;error&amp;#039;,&lt;br /&gt;
			range = &amp;#039;dash&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		age_in_years_nts = {        -- {{age in years nts}}&lt;br /&gt;
			show = &amp;#039;y&amp;#039;,&lt;br /&gt;
			abbr = &amp;#039;abbr_raw&amp;#039;,&lt;br /&gt;
			negative = &amp;#039;error&amp;#039;,&lt;br /&gt;
			range = &amp;#039;dash&amp;#039;,&lt;br /&gt;
			format = &amp;#039;format_commas&amp;#039;,&lt;br /&gt;
			sortable = &amp;#039;on&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		age_infant = {              -- {{age for infant}}&lt;br /&gt;
			-- Do not set show because special processing is done later.&lt;br /&gt;
			abbr = &amp;#039;abbr_off&amp;#039;,&lt;br /&gt;
			disp = &amp;#039;disp_age&amp;#039;,&lt;br /&gt;
			sortable = &amp;#039;on&amp;#039;,&lt;br /&gt;
			age = true,&lt;br /&gt;
		},&lt;br /&gt;
		age_m = {                   -- {{age in months}}&lt;br /&gt;
			show = &amp;#039;m&amp;#039;,&lt;br /&gt;
			disp = &amp;#039;disp_raw&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		age_w = {                   -- {{age in weeks}}&lt;br /&gt;
			show = &amp;#039;w&amp;#039;,&lt;br /&gt;
			disp = &amp;#039;disp_raw&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		age_wd = {                  -- {{age in weeks and days}}&lt;br /&gt;
			show = &amp;#039;wd&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		age_yd = {                  -- {{age in years and days}}&lt;br /&gt;
			show = &amp;#039;yd&amp;#039;,&lt;br /&gt;
			format = &amp;#039;format_commas&amp;#039;,&lt;br /&gt;
			sep = args.sep == &amp;#039;and&amp;#039; and &amp;#039;sep_serialcomma&amp;#039; or nil,&lt;br /&gt;
			age = true,&lt;br /&gt;
		},&lt;br /&gt;
		age_yd_nts = {              -- {{age in years and days nts}}&lt;br /&gt;
			show = &amp;#039;yd&amp;#039;,&lt;br /&gt;
			format = &amp;#039;format_commas&amp;#039;,&lt;br /&gt;
			sep = args.sep == &amp;#039;and&amp;#039; and &amp;#039;sep_serialcomma&amp;#039; or nil,&lt;br /&gt;
			sortable = &amp;#039;on&amp;#039;,&lt;br /&gt;
			age = true,&lt;br /&gt;
		},&lt;br /&gt;
		age_ym = {                  -- {{age in years and months}}&lt;br /&gt;
			show = &amp;#039;ym&amp;#039;,&lt;br /&gt;
			sep = args.sep == &amp;#039;and&amp;#039; and &amp;#039;sep_serialcomma&amp;#039; or nil,&lt;br /&gt;
		},&lt;br /&gt;
		age_ymd = {                 -- {{age in years, months and days}}&lt;br /&gt;
			show = &amp;#039;ymd&amp;#039;,&lt;br /&gt;
			range = &amp;#039;dash&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		age_ymwd = {                -- {{age in years, months, weeks and days}}&lt;br /&gt;
			show = &amp;#039;ymwd&amp;#039;,&lt;br /&gt;
			wantMixture = true,&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
	local spec = specs[name]&lt;br /&gt;
	if not spec then&lt;br /&gt;
		return message(&amp;#039;指定的模板名称无效&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	if name == &amp;#039;age_days&amp;#039; then&lt;br /&gt;
		local su = stripToNil(args[&amp;#039;show unit&amp;#039;])&lt;br /&gt;
		if su then&lt;br /&gt;
			if su == &amp;#039;abbr&amp;#039; or su == &amp;#039;full&amp;#039; then&lt;br /&gt;
				spec.disp = nil&lt;br /&gt;
				spec.abbr = su == &amp;#039;abbr&amp;#039; and &amp;#039;abbr_on&amp;#039; or nil&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local partial, autofill&lt;br /&gt;
	local range = stripToNil(args.range) or spec.range&lt;br /&gt;
	if range then&lt;br /&gt;
		-- Suppose partial dates are used and age could be 11 or 12 years.&lt;br /&gt;
		-- &amp;quot;|range=&amp;quot; (empty value) has no effect (spec is used).&lt;br /&gt;
		-- &amp;quot;|range=yes&amp;quot; or spec.range == true sets range = true (gives &amp;quot;11或12&amp;quot;)&lt;br /&gt;
		-- &amp;quot;|range=dash&amp;quot; or spec.range == &amp;#039;dash&amp;#039; sets range = &amp;#039;dash&amp;#039; (gives &amp;quot;11—12&amp;quot;).&lt;br /&gt;
		-- &amp;quot;|range=no&amp;quot; or spec.range == &amp;#039;no&amp;#039; sets range = nil and fills each date in the diff (gives &amp;quot;12&amp;quot;).&lt;br /&gt;
		--     (&amp;quot;on&amp;quot; is equivalent to &amp;quot;yes&amp;quot;, and &amp;quot;off&amp;quot; is equivalent to &amp;quot;no&amp;quot;).&lt;br /&gt;
		-- &amp;quot;|range=OTHER&amp;quot; sets range = nil and rejects partial dates.&lt;br /&gt;
		range = ({ dash = &amp;#039;dash&amp;#039;, off = &amp;#039;no&amp;#039;, no = &amp;#039;no&amp;#039;, [true] = true })[range] or yes(range)&lt;br /&gt;
		if range then&lt;br /&gt;
			partial = true  -- accept partial dates with a possible age range for the result&lt;br /&gt;
			if range == &amp;#039;no&amp;#039; then&lt;br /&gt;
				autofill = true  -- missing month/day in first or second date are filled from other date or 1&lt;br /&gt;
				range = nil&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local getopt = {&lt;br /&gt;
		fix = yes(args.fix),&lt;br /&gt;
		flag = stripToNil(args.flag) or spec.flag,&lt;br /&gt;
		omitZero = spec.omitZero,&lt;br /&gt;
		partial = partial,&lt;br /&gt;
		wantMixture = spec.wantMixture,&lt;br /&gt;
	}&lt;br /&gt;
	local date1, date2 = getDates(frame, getopt)&lt;br /&gt;
	if type(date1) == &amp;#039;string&amp;#039; then&lt;br /&gt;
		return date1&lt;br /&gt;
	end&lt;br /&gt;
	local useAge = spec.age&lt;br /&gt;
	if args.age ~= nil then&lt;br /&gt;
		useAge = yes(args.age, spec.age)&lt;br /&gt;
	end&lt;br /&gt;
	local format = stripToNil(args.format)&lt;br /&gt;
	local spell = spellOptions[format]&lt;br /&gt;
	if format then&lt;br /&gt;
		format = &amp;#039;format_&amp;#039; .. format&lt;br /&gt;
	elseif name == &amp;#039;age_days&amp;#039; and getopt.textdates then&lt;br /&gt;
		format = &amp;#039;format_commas&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	local parms = {&lt;br /&gt;
		diff = date2:subtract(date1, { fill = autofill }),&lt;br /&gt;
		wantDuration = spec.duration or yes(args.duration),&lt;br /&gt;
		range = range,&lt;br /&gt;
		wantSc = yes(args.sc),&lt;br /&gt;
		show = args.show == &amp;#039;hide&amp;#039; and &amp;#039;hide&amp;#039; or spec.show,&lt;br /&gt;
		abbr = useAge and &amp;#039;abbr_age&amp;#039; or spec.abbr,&lt;br /&gt;
		disp = spec.disp,&lt;br /&gt;
		extra = (getopt.usesCurrent and format ~= &amp;#039;format_raw&amp;#039;) and &amp;#039;&amp;lt;span class=&amp;quot;currentage&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;#039; or nil,&lt;br /&gt;
		format = format or spec.format,&lt;br /&gt;
		round = yes(args.round),&lt;br /&gt;
		sep = spec.sep,&lt;br /&gt;
		sortable = translateParameters.sortable[args.sortable or spec.sortable],&lt;br /&gt;
		spell = spell,&lt;br /&gt;
	}&lt;br /&gt;
	if (spec.negative or frame.args.negative) == &amp;#039;error&amp;#039; and parms.diff.isnegative then&lt;br /&gt;
		return message(&amp;#039;第二个日期不应该在第一个日期之前&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	return dateDifference(parms)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function bda(frame)&lt;br /&gt;
	-- Implement [[Template:Birth date and age]].&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	local options = { noMissing=true, single=true }&lt;br /&gt;
	local date = getDates(frame, options)&lt;br /&gt;
	if type(date) == &amp;#039;string&amp;#039; then&lt;br /&gt;
		return date  -- error text&lt;br /&gt;
	end&lt;br /&gt;
	local Date = getExports(frame)&lt;br /&gt;
	local diff = Date(&amp;#039;currentdate&amp;#039;) - date&lt;br /&gt;
	if diff.isnegative or diff.years &amp;gt; 150 then&lt;br /&gt;
		return message(&amp;#039;计算年龄所需的出生日期无效&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	local disp, show = &amp;#039;disp_raw&amp;#039;, &amp;#039;y&amp;#039;&lt;br /&gt;
	if diff.years &amp;lt; 2 then&lt;br /&gt;
		disp = &amp;#039;disp_age&amp;#039;&lt;br /&gt;
		if diff.years == 0 and diff.months == 0 then&lt;br /&gt;
			show = &amp;#039;d&amp;#039;&lt;br /&gt;
		else&lt;br /&gt;
			show = &amp;#039;m&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local result = &amp;#039;%-Y年%B月%-d日&amp;#039;&lt;br /&gt;
	result = &amp;#039;（&amp;lt;span class=&amp;quot;bday&amp;quot;&amp;gt;%-Y-%m-%d&amp;lt;/span&amp;gt;) &amp;lt;/span&amp;gt;&amp;#039; .. result&lt;br /&gt;
	result = &amp;#039;&amp;lt;span style=&amp;quot;display:none&amp;quot;&amp;gt; &amp;#039; ..&lt;br /&gt;
		date:text(result) ..&lt;br /&gt;
		&amp;#039;&amp;lt;span class=&amp;quot;noprint ForceAgeToShow&amp;quot;&amp;gt; &amp;#039; ..&lt;br /&gt;
		&amp;#039;（&amp;#039; ..&lt;br /&gt;
		dateDifference({&lt;br /&gt;
			diff = diff,&lt;br /&gt;
			show = show,&lt;br /&gt;
			abbr = &amp;#039;abbr_off&amp;#039;,&lt;br /&gt;
			disp = disp,&lt;br /&gt;
			sep = &amp;#039;sep_space&amp;#039;,&lt;br /&gt;
		}) ..&lt;br /&gt;
		&amp;#039;）&amp;lt;/span&amp;gt;&amp;#039;&lt;br /&gt;
	local warnings = tonumber(frame.args.warnings)&lt;br /&gt;
	if warnings and warnings &amp;gt; 0 then&lt;br /&gt;
		local good = {&lt;br /&gt;
			df = true,&lt;br /&gt;
			mf = true,&lt;br /&gt;
			day = true,&lt;br /&gt;
			day1 = true,&lt;br /&gt;
			month = true,&lt;br /&gt;
			month1 = true,&lt;br /&gt;
			year = true,&lt;br /&gt;
			year1 = true,&lt;br /&gt;
		}&lt;br /&gt;
		local invalid&lt;br /&gt;
		local imax = options.textdates and 1 or 3&lt;br /&gt;
		for k, _ in pairs(args) do&lt;br /&gt;
			if type(k) == &amp;#039;number&amp;#039; then&lt;br /&gt;
				if k &amp;gt; imax then&lt;br /&gt;
					invalid = tostring(k)&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				if not good[k] then&lt;br /&gt;
					invalid = k&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if invalid then&lt;br /&gt;
			result = result .. message(invalid .. &amp;#039;参数无效&amp;#039;, &amp;#039;warning&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function dateToGsd(frame)&lt;br /&gt;
	-- Implement [[Template:Gregorian serial date]].&lt;br /&gt;
	-- Return Gregorian serial date of the given date, or the current date.&lt;br /&gt;
	-- The returned value is negative for dates before 1 January 1 AD&lt;br /&gt;
	-- despite the fact that GSD is not defined for such dates.&lt;br /&gt;
	local date = getDates(frame, { wantMixture=true, single=true })&lt;br /&gt;
	if type(date) == &amp;#039;string&amp;#039; then&lt;br /&gt;
		return date&lt;br /&gt;
	end&lt;br /&gt;
	return tostring(date.gsd)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function jdToDate(frame)&lt;br /&gt;
	-- Return formatted date from a Julian date.&lt;br /&gt;
	-- The result includes a time if the input includes a fraction.&lt;br /&gt;
	-- The word &amp;#039;Julian&amp;#039; is accepted for the Julian calendar.&lt;br /&gt;
	local Date = getExports(frame)&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	local date = Date(&amp;#039;juliandate&amp;#039;, args[1], args[2])&lt;br /&gt;
	if date then&lt;br /&gt;
		return date:text()&lt;br /&gt;
	end&lt;br /&gt;
	return message(&amp;#039;需要有效的儒略历日期&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function dateToJd(frame)&lt;br /&gt;
	-- Return Julian date (a number) from a date which may include a time,&lt;br /&gt;
	-- or the current date (&amp;#039;currentdate&amp;#039;) or current date and time (&amp;#039;currentdatetime&amp;#039;).&lt;br /&gt;
	-- The word &amp;#039;Julian&amp;#039; is accepted for the Julian calendar.&lt;br /&gt;
	local Date = getExports(frame)&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	local date = Date(args[1], args[2], args[3], args[4], args[5], args[6], args[7])&lt;br /&gt;
	if date then&lt;br /&gt;
		return tostring(date.jd)&lt;br /&gt;
	end&lt;br /&gt;
	return message(&amp;#039;需要有效的年/月/日或“currentdate”（当前）&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function timeInterval(frame)&lt;br /&gt;
	-- Implement [[Template:Time interval]].&lt;br /&gt;
	-- There are two positional arguments: date1, date2.&lt;br /&gt;
	-- The default for each is the current date and time.&lt;br /&gt;
	-- Result is date2 - date1 formatted.&lt;br /&gt;
	local Date = getExports(frame)&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	local parms = {&lt;br /&gt;
		wantDuration = yes(args.duration),&lt;br /&gt;
		range = yes(args.range) or (args.range == &amp;#039;dash&amp;#039; and &amp;#039;dash&amp;#039; or nil),&lt;br /&gt;
		wantSc = yes(args.sc),&lt;br /&gt;
	}&lt;br /&gt;
	local fix = yes(args.fix) and &amp;#039;fix&amp;#039; or &amp;#039;&amp;#039;&lt;br /&gt;
	local date1 = Date(fix, &amp;#039;partial&amp;#039;, stripToNil(args[1]) or &amp;#039;currentdatetime&amp;#039;)&lt;br /&gt;
	if not date1 then&lt;br /&gt;
		return message(&amp;#039;第一个参数中的开始日期无效&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	local date2 = Date(fix, &amp;#039;partial&amp;#039;, stripToNil(args[2]) or &amp;#039;currentdatetime&amp;#039;)&lt;br /&gt;
	if not date2 then&lt;br /&gt;
		return message(&amp;#039;第二个参数中的结束日期无效&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	parms.diff = date2 - date1&lt;br /&gt;
	for argname, translate in pairs(translateParameters) do&lt;br /&gt;
		local parm = stripToNil(args[argname])&lt;br /&gt;
		if parm then&lt;br /&gt;
			parm = translate[parm]&lt;br /&gt;
			if parm == nil then  -- test for nil because false is a valid setting&lt;br /&gt;
				return message(&amp;#039;参数&amp;#039; .. argname .. &amp;#039;=&amp;#039; .. args[argname] .. &amp;#039;无效&amp;#039;)&lt;br /&gt;
			end&lt;br /&gt;
			parms[argname] = parm&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if parms.round then&lt;br /&gt;
		local round = parms.round&lt;br /&gt;
		local show = parms.show&lt;br /&gt;
		if round ~= &amp;#039;on&amp;#039; then&lt;br /&gt;
			if show then&lt;br /&gt;
				if show.id ~= round then&lt;br /&gt;
					return message(&amp;#039;参数show=&amp;#039; .. args.show .. &amp;#039;与round=&amp;#039; .. args.round .. &amp;#039;冲突&amp;#039;)&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				parms.show = translateParameters.show[round]&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		parms.round = true&lt;br /&gt;
	end&lt;br /&gt;
	return dateDifference(parms)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return {&lt;br /&gt;
	age_generic = ageGeneric,           -- can emulate several age templates&lt;br /&gt;
	birth_date_and_age = bda,           -- Template:Birth_date_and_age&lt;br /&gt;
	gsd = dateToGsd,                    -- Template:Gregorian_serial_date&lt;br /&gt;
	extract = dateExtract,              -- Template:Extract&lt;br /&gt;
	jd_to_date = jdToDate,              -- Template:?&lt;br /&gt;
	JULIANDAY = dateToJd,               -- Template:JULIANDAY&lt;br /&gt;
	time_interval = timeInterval,       -- Template:Time_interval&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>wikiw&gt;Ericliu1912</name></author>
	</entry>
</feed>