پودمان:Year in other calendars

از ویکی‌پدیا، دانشنامهٔ آزاد
پرش به: ناوبری، جستجو
نماد توضیحات توضیحات پودمان[ایجاد]
-- برای فارسی‌سازی بهتر، بخش‌هایی از این پودمان تغییر کرده‌است. لطفاً هنگام به‌روزرسانی دقت کنید.
-- Load dependencies.
local getArgs = require( 'Module:Arguments' ).getArgs
local htmlBuilder = require( 'Module:HtmlBuilder' )
local makeNavbar = require( 'Module:Navbar' )._navbar
local numToRoman = require( 'Module:Roman' ).main
local numToArmenian = require( 'Module:Armenian' ).main
local getRegnal = require( 'Module:British regnal year' ).main
local japaneseEra = require( 'Module:Japanese calendar' ).era()
local numConverter = require( 'Module:Numeral converter' ).convert
 
-- Define constants.
local lang = mw.getLanguage('en')
local currentYear = tonumber( lang:formatDate( 'Y' ) )
 
--------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------
 
local function isInteger( num )
	-- Checks if a value is an integer. If so, returns the value converted to a number.
	-- If not, returns false.
	num = tonumber( num )
	if num and math.floor( num ) == num and num ~= math.huge then
		return num
	else
		return false
	end
end
 
local function BCToNum( s )
	-- Converts strings of the format "n BC" to their corresponding
	-- numerical values.
	if type( s ) ~= 'string' then
		return nil
	end
	-- لوآ از non capturing پشتیبانی نمی‌کند به همین خاطر برای فارسی‌سازی بهتر، دستور زیر بازنویسی شده‌است.
	s = mw.ustring.match( mw.ustring.upper( s ), '^([1-9]%d*)%s*BC$' ) or
	    mw.ustring.match( s, '^([1-9]%d*)%s*پیش از میلاد$' ) or
	    mw.ustring.match( s, '^([1-9]%d*)%s*پیش از میلاد مسیح$' ) or
	    mw.ustring.match( s, '^([1-9]%d*)%s*قبل از میلاد$' ) or
	    mw.ustring.match( s, '^([1-9]%d*)%s*قبل از میلاد مسیح$' )
 
	if not s then
		return nil
	end
	local num = tonumber( s )
	num = ( num - 1 ) * -1
	return num
end
 
local function numToBC( num )
	-- For BC years, returns a string with the year name appended with " BC".
	-- Otherwise returns nil.
	num = isInteger( num )
	if not num then return end
	if num <= 0 then
		return mw.ustring.format( '%d پیش از میلاد', 1 - num )
	end
end
 
local function formatNegative(s)
	-- Replaces hyphens in a string with minus signs if the hyphen comes before a number.
	s = mw.ustring.gsub( s, '%-(%d)', '−%1' )
	return s
end
 
--------------------------------------------------------------------
-- Calendar box class definition
--------------------------------------------------------------------
 
local calendarBox = {}
calendarBox.__index = calendarBox
 
function calendarBox:new( init )
	init = type( init ) == 'table' and init or {}
	local obj = {}
	-- خط زیر برای صحیح کارکردن در وبکی‌پدیای فارسی تغییر کرده‌است.
	local pagename = mw.ustring.gsub(numConverter('en', mw.title.getCurrentTitle().text), '[^%d]+', '')
 
	-- Set the year. If the year is specified as an argument, use that.
	-- Otherwise, use the page name if it is valid. If the pagename isn't
	-- valid, use the current year.
	local yearNum = isInteger( numConverter('en', init.year) )
	if yearNum then -- First, see if the year parameter is a number.
		self.year = yearNum
	else
		local yearBC = BCToNum( numConverter('en', init.year) )
		if yearBC then -- Second, see if the year parameter is a "yyyy BC" string.
			self.year = yearBC
		else
			local pageNum = isInteger( pagename )
			if pageNum then -- Third, see if the pagename is an integer.
				self.year = pageNum
			else
				local pageBC = BCToNum( pagename )
				if pageBC then -- Fourth, see if the pagename is a "yyyy BC" string.
					self.year = pageBC
				else
					self.year = currentYear -- If none of the above apply, use the current year.
				end
			end
		end
	end
 
	-- Set year text values.
	self.BCYearName = numToBC( self.year )
	if self.BCYearName then
		self.yearText = self.BCYearName
	else
		self.yearText = tostring( self.year )
	end
 
	-- Set other fields.
	self.caption = self.yearText
	self.footnotes = init.footnotes
	self.navbar = init.navbar
 
	return setmetatable( obj, {
			__index = self
		})
end
 
function calendarBox:setCaption( s )
	-- Sets the calendar box caption.
	if type( s ) ~= 'string' or s == '' then return end
	self.caption = s
end
 
function calendarBox:addCalendar( obj )
	-- Adds a calendar or a calendar group.
	if type( obj ) ~= 'table' and type( obj.new ) ~= 'function' then return end -- Exit if the object is invalid.
	self.calendars = self.calendars or {}
	table.insert( self.calendars, obj )
end
 
-- Add an alias for adding calendar groups. The function is the same, but it might be confusing for users
-- to have to use the name "addCalendar" for a calendar group.
calendarBox.addCalendarGroup = calendarBox.addCalendar
 
function calendarBox:export()
	-- Outputs the calendar box wikitext.
	local root = htmlBuilder.create( 'table' )
	-- Export the calendar box headers.
	root
	.addClass( 'infobox' )
	.addClass( 'vevent' )
	.css( 'width', '22em' )
	.tag( 'caption' )
	.css( 'font-size', '125%' )
	.tag( 'span' )
	.addClass( 'summary' )
	.addClass( 'dtstart' )
	.wikitext( self.caption )
 
	-- Export the calendars and calendar groups. "calendar:export()" works for both kinds
	-- of objects. Some export functions can return nil, so we need to check for that.
	if type( self.calendars ) == 'table' then
		for _, calendar in ipairs( self.calendars ) do
			local calendarText = calendar:export()
			if type( calendarText ) == 'string' then
				root.wikitext( calendarText )
			end
		end
	end
 
	-- Add footnotes.
	if type( self.footnotes ) == 'string' and self.footnotes ~= '' then
		root
		.tag( 'tr' )
		.tag( 'td' )
		.attr( 'colspan', '2' )
		.wikitext( mw.ustring.format( '<small>%s</small>', self.footnotes ) )
	end
 
	-- Add navbar.
	if type( self.navbar ) == 'string' and self.navbar ~= '' then
		root
		.tag( 'tr' )
		.tag( 'td' )
		.attr( 'colspan', '2' )
		.css( 'text-align', 'center' )
		.wikitext( makeNavbar{ self.navbar } )
	end
 
	return tostring( root )
end
 
--------------------------------------------------------------------
-- Calendar group class definition
--------------------------------------------------------------------
 
--  Calendar groups are used to group different calendars together. 
--  Previously, the template did this by including a table row with
--  no year value. By using objects we can do the same thing more
--  semantically.
 
local calendarGroup = {}
calendarGroup.__index = calendarGroup
 
function calendarGroup:new( init )
	init = type( init ) == 'table' and init or {}
	local obj = {}
 
	-- Get the heading and throw an error if it is invalid.
	obj.heading = init.heading
	if type( obj.heading ) ~= 'string' then
		error( 'calendarGroup: no heading detected' )
	end
 
	-- Set the metatable and return the object.
	self.__index = self
	return setmetatable( obj, {
			__index = self
		})
end
 
function calendarGroup:addCalendar( calendar )
	-- Adds a calendar object to the calendar group.
	self.calendars = self.calendars or {}
	if type( calendar ) == 'table' and type( calendar.getLink ) == 'function' then
		table.insert( self.calendars, calendar )
	end
end
 
function calendarGroup:export()
	-- Exports the calendar group's wikitext.
	-- Indent and italicise each calendar's link if it exists.
	for i, calendar in ipairs( self.calendars ) do
		local link = calendar:getLink()
		if type( link ) == 'string' then
			self.calendars[ i ]:setRawLink( mw.ustring.format( "&nbsp;- ''%s''", link ) )
		end
	end
	-- Create the heading row html and export the calendar objects.
	local ret = htmlBuilder.create()
	ret
	.tag( 'tr' )
	.tag( 'td' )
	.wikitext( self.heading )
	.done()
	.tag( 'td' ) -- Use a blank tag to make the html look nice.
	.allDone()
	for _, calendar in ipairs( self.calendars ) do
		ret.wikitext( calendar:export() )
	end
	return tostring( ret )
end
 
--------------------------------------------------------------------
-- Calendar class definition
--------------------------------------------------------------------
 
local calendar = {}
calendar.__index = calendar
calendar.type = 'calendar'
 
function calendar:new()
	local obj = {}
	return setmetatable( obj, {
			__index = self
		})
end
 
function calendar:setLink( link, display )
	-- Sets the calendar's wikilink, with optional display text and italics.
	if type( link ) ~= 'string' or link == '' then return end
	display = type( display ) == 'string' and display ~= '' and display
	if display then
		self.link = mw.ustring.format( '[[%s|%s]]', link, display )
	else
		self.link = mw.ustring.format( '[[%s]]', link )
	end
end
 
function calendar:setRawLink( s )
	-- Sets the calendar's wikilink as raw wikitext.
	if type( s ) ~= 'string' or s == '' then return end
	self.link = s
end
 
function calendar:getLink()
	-- Returns the calendar's link value.
	return self.link
end
 
function calendar:setYear( year )
	-- Sets a single year. Can be passed either a string or a number.
	-- If passed as a number, it is formatted with minus signs instead of hyphens.
	-- If passed as a string, no minus-sign formatting occurs; this should be done in the individual calendar definitions.
	if type( year ) == 'number' then
		year = tostring( year )
		self.year = formatNegative( year )
	elseif type( year ) == 'string' then
		self.year = year
	end
end
 
function calendar:setYearRange( year1, year2 )
	-- Sets a year range. Must be passed two numbers.
	if type( year1 ) == 'number' and type( year2 ) == 'number' then
		local year
		if year1 < 0 or year2 < 0 then -- Leave a gap for negative years to avoid having a minus sign and a dash right next to each other.
			year = mw.ustring.format( '%d – %d', year1, year2 )
			year = formatNegative( year )
		else
			year = mw.ustring.format( '%d–%d', year1, year2 )
		end
		self.year = year
	end
end
 
function calendar:export()
	-- Outputs the calendar wikitext.
	-- Exit if no link has been specified.
	local link = self.link
	if type( link ) ~= 'string' or link == '' then return end
 
	-- If no year has been specified, set the year value to N/A.
	local year = self.year
	if type( year ) ~= 'string' or year == '' then
		year = "''نامعلوم''"
	end
 
	-- Build the table row.
	local ret = htmlBuilder.create()
	ret
	.tag( 'tr' )
	.tag( 'td' )
	.wikitext( link )
	.done()
	.tag( 'td' )
	.wikitext( numConverter('fa', year) )
	.allDone()
	return tostring( ret )
end
 
--------------------------------------------------------------------
-- Build the box
--------------------------------------------------------------------
 
local function makeCalendarBox( args )
	-- Initiate the box and get the year values.
	local init = args
	init.navbar = 'سال در گاه‌شماری‌های دیگر'
	local box = calendarBox:new( init )
	local year = box.year
	local yearText = box.yearText
 
	-- Set the caption.
	box:setCaption( numConverter('fa', box.caption) .. ' در گاه‌شماری‌های دیگر' )
 
	----------------------------------------------------------------------
	-- Iranian calendar
	----------------------------------------------------------------------
 
	local iranian = calendar:new()
	iranian:setLink( 'گاه‌شماری در ایران', 'گاه‌شماری ایرانی' )
	if year - 621 > 0 then
		iranian:setYearRange( year - 622, year - 621 )
	else
		iranian:setYear( mw.ustring.format( '%d پیش از اکنون&nbsp;– %d پیش از اکنون', 622 - year, 621 - year ) )
	end
	box:addCalendar( iranian )
 
	----------------------------------------------------------------------
	-- Gregorian calendar
	----------------------------------------------------------------------
 
	local gregorian = calendar:new()
	gregorian:setLink( 'گاه‌شماری میلادی' )
	-- Get the year link.
	local gregcal = args.gregcal
	if type( gregcal ) == 'string' and gregcal ~= '' then
		gregorian.yearLink = mw.ustring.format( '[[%s|%s]]', gregcal, yearText )
	else
		gregorian.yearLink = yearText
	end
	-- Set the year.
	gregorian.romanYear = numToRoman{ year }
	if gregorian.romanYear then
		gregorian:setYear( mw.ustring.format(
				[[%s<br /><span style="font-family: serif;">''%s''</span>]],
				gregorian.yearLink, gregorian.romanYear
				) )
	else
		gregorian:setYear( gregorian.yearLink )
	end
	box:addCalendar( gregorian ) 
 
	----------------------------------------------------------------------
	-- Ethiopian calendar
	----------------------------------------------------------------------
 
	local ethiopian = calendar:new()
	ethiopian:setLink( 'گاه‌شماری اتیوپیایی' )
	ethiopian:setYearRange( year - 8, year - 7 )
	box:addCalendar( ethiopian )
 
	----------------------------------------------------------------------
	-- Armenian calendar
	----------------------------------------------------------------------
 
	local armenian = calendar:new()
	armenian:setLink( 'گاه‌شماری ارمنی' )
	if year > 551 then
		local armenianYear = year - 551
		armenian:setYear( mw.ustring.format( '%s<br />ԹՎ %s', armenianYear, numToArmenian( armenianYear ) ) )
	end
	box:addCalendar( armenian )
 
	----------------------------------------------------------------------
	-- Islamic calendar
	----------------------------------------------------------------------
 
	local islamic = calendar:new()
	islamic:setLink( 'گاه‌شماری هجری قمری', 'گاه‌شماری اسلامی')
	local islamicMult = 1.030684 -- the factor to multiply by
	local islamicSub = 621.5643 -- the factor to subtract by
	if year - 621 > 0 then
		local year1 = math.floor( islamicMult * ( year - islamicSub ) )
		local year2 = math.floor( islamicMult * ( year - islamicSub + 1 ) )
		islamic:setYearRange( year1, year2 )
	else
		local year1 = math.ceil( -islamicMult * ( year - islamicSub ) )
		local year2 = math.ceil( -islamicMult * ( year - islamicSub + 1 ) )
		islamic:setYear( mw.ustring.format( '%d پیش از هجرت&nbsp;– %d پیش از هجرت', year1, year2 ) )
	end
	box:addCalendar( islamic )
 
	----------------------------------------------------------------------
	-- Igbo calendar
	----------------------------------------------------------------------
 
	-- In the old template this was a calendar group with just one calendar; intentionally adding this as a single
	-- calendar here, as the previous behaviour looked like a mistake.
	local igbo = calendar:new()
	igbo:setLink( 'گاه‌شماری ایگبو' )
	igbo:setYearRange( year - 1000, year - 999 )
	box:addCalendar( igbo )
 
	----------------------------------------------------------------------
	-- Assyrian calendar
	----------------------------------------------------------------------
 
	local assyrian = calendar:new()
	assyrian:setLink( 'گاه‌شماری آشوری' )
	assyrian:setYear( year + 4750 )
	box:addCalendar( assyrian )
 
	----------------------------------------------------------------------
	-- Berber calendar
	----------------------------------------------------------------------
 
	local berber = calendar:new()
	berber:setLink( 'گاه‌شماری بربری' )
	berber:setYear( year + 950 )
	box:addCalendar( berber )
 
	----------------------------------------------------------------------
	-- Bengali calendar
	----------------------------------------------------------------------
 
	local bengali = calendar:new()
	bengali:setLink( 'گاه‌شماری بنگالی' )
	bengali:setYear( year - 593 )
	box:addCalendar( bengali )
 
	----------------------------------------------------------------------
	-- Bahá'í calendar
	----------------------------------------------------------------------
 
	local bahai = calendar:new()
	bahai:setLink( "گاه‌شماری بهائی" )
	bahai:setYearRange( year - 1844, year - 1843 )
	box:addCalendar( bahai )
 
	----------------------------------------------------------------------
	-- Buddhist calendar
	----------------------------------------------------------------------
 
	local buddhist = calendar:new()
	buddhist:setLink( 'گاه‌شماری بودایی' )
	buddhist:setYear( year + 544 )
	box:addCalendar( buddhist )
 
	----------------------------------------------------------------------
	-- Byzantine calendar
	----------------------------------------------------------------------
 
	local byzantine = calendar:new()
	byzantine:setLink( 'گاه‌شماری بیزانسی' )
	byzantine:setYearRange( year + 5508, year + 5509 )
	box:addCalendar( byzantine )
 
	----------------------------------------------------------------------
	-- Juche calendar
	----------------------------------------------------------------------
 
	local juche = calendar:new()
	juche:setLink( 'گاه‌شماری کره شمالی', 'گاه‌شماری جوچه' )
	if year > 1911 then
		juche:setYear( year - 1911 )
	end
	box:addCalendar( juche )
 
	----------------------------------------------------------------------
	-- Chinese calendar
	----------------------------------------------------------------------
 
	local chinese = calendar:new()
	chinese:setLink( 'گاه‌شماری چینی' )
 
	-- Define the information for the "heavenly stems" and "earthly branches" year cycles.
	-- See [[Chinese calendar#Cycle of years]] for information.
 
	local heavenlyStems = {
		{ '甲', 'چوب' },   -- 1
		{ '乙', 'چوب' },   -- 2
		{ '丙', 'آتش' },   -- 3
		{ '丁', 'آتش' },   -- 4
		{ '戊', 'زمین' },  -- 5
		{ '己', 'زمین' },  -- 6
		{ '庚', 'فلز' },  -- 7
		{ '辛', 'فلز' },  -- 8
		{ '壬', 'آب' },  -- 9
		{ '癸', 'آب' }   -- 10
	}
 
	local earthlyBranches = {
		{ '子', '[[موش (منطقةالبروج)|موش]]' },           -- 1
		{ '丑', '[[گاو نر (منطقةالبروج)|گاو نر]]' },             -- 2
		{ '寅', '[[ببر (منطقةالبروج)|ببر]]' },       -- 3
		{ '卯', '[[خرگوش (منطقةالبروج)|خرگوش]]' },     -- 4
		{ '辰', '[[اژدها (منطقةالبروج)|اژدها]]' },     -- 5
		{ '巳', '[[مار (منطقةالبروج)|مار]]' },       -- 6
		{ '午', '[[اسب (منطقةالبروج)|اسب]]' },       -- 7
		{ '未', '[[بز (منطقةالبروج)|بز]]' },         -- 8
		{ '申', '[[میمون (منطقةالبروج)|میمون]]' },     -- 9
		{ '酉', '[[خروس (منطقةالبروج)|خروس]]' },   -- 10
		{ '戌', '[[سگ (منطقةالبروج)|سگ]]' },           -- 11
		{ '亥', '[[خوک (منطقةالبروج)|خوک]]' }            -- 12
	}
 
	-- Calculate the cycle numbers from the year. The first sexagenary year corresponds to the ''previous'' year's entry
	-- in [[Chinese calendar correspondence table]], as the Chinese New Year doesn't happen until Jan/Feb in
	-- Gregorian years.
	local sexagenaryYear1 = ( year - 4 ) % 60
	local sexagenaryYear2 = ( year - 3 ) % 60
	local heavenlyNum1 = sexagenaryYear1 % 10
	local heavenlyNum2 = sexagenaryYear2 % 10
	local earthlyNum1 = sexagenaryYear1 % 12
	local earthlyNum2 = sexagenaryYear2 % 12
 
	-- If the value is 0 increase it by one cycle so that we can use it with Lua arrays.
	if heavenlyNum1 == 0 then
		heavenlyNum1 = 10
	end
	if heavenlyNum2 == 0 then
		heavenlyNum2 = 10
	end
	if earthlyNum1 == 0 then
		earthlyNum1 = 12
	end
	if earthlyNum2 == 0 then
		earthlyNum2 = 12
	end
 
	-- Get the data tables for each permutation.
	local heavenlyTable1 = heavenlyStems[ heavenlyNum1 ]
	local heavenlyTable2 = heavenlyStems[ heavenlyNum2 ]
	local earthlyTable1 = earthlyBranches[ earthlyNum1 ]
	local earthlyTable2 = earthlyBranches[ earthlyNum2 ]
 
	-- Work out the continously-numbered year. (See [[Chinese calendar#Continuously numbered years]].)
	local year1 = year + 2696
	local year2 = year + 2697
	local year1Alt = year1 - 60
	local year2Alt = year2 - 60
 
	-- Format any negative numbers.
	year1 = formatNegative( tostring( year1 ) )
	year2 = formatNegative( tostring( year2 ) )
	year1Alt = formatNegative( tostring( year1Alt ) )
	year2Alt = formatNegative( tostring( year2Alt ) )
 
	-- Return all of that data in a (hopefully) reader-friendly format.
	chinese:setYear( mw.ustring.format(
			[=[[[:en:Sexagenary cycle|%s%s]]年 <small>(%s&nbsp;%s)</small><br />%s یا %s<br />&nbsp;&nbsp;&nbsp;&nbsp;''—&nbsp;تا&nbsp;—''<br />%s%s年 <small>(%s&nbsp;%s)</small><br />%s یا %s]=],
			heavenlyTable1[ 1 ],
			earthlyTable1[ 1 ],
			heavenlyTable1[ 2 ],
			earthlyTable1[ 2 ],
			year1,
			year1Alt,
			heavenlyTable2[ 1 ],
			earthlyTable2[ 1 ],
			heavenlyTable2[ 2 ],
			earthlyTable2[ 2 ],
			year2,
			year2Alt
			) )
 
	box:addCalendar( chinese )
 
	----------------------------------------------------------------------
	-- Thai solar calendar
	----------------------------------------------------------------------
 
	local thai = calendar:new()
	thai:setLink( 'گاه‌شماری خورشیدی تایلندی' )
	thai:setYear( year + 543 )
	box:addCalendar( thai )
 
	----------------------------------------------------------------------
	-- Discordian calendar
	----------------------------------------------------------------------
 
	local discordian = calendar:new()
	discordian:setLink( 'گاه‌شماری دیسکوردیان' )
	discordian:setYear( year + 1166 )
	box:addCalendar( discordian )
 
	----------------------------------------------------------------------
	-- Japanese calendar
	----------------------------------------------------------------------
 
	local japanese = calendar:new()
	japanese:setLink( 'گاه‌شماری ژاپنی' )
 
	japanese.thisEra = japaneseEra:new{ year = year }
	if japanese.thisEra then
		local japaneseYearText = {}
		japanese.oldEra = japanese.thisEra:getOldEra()
		if japanese.oldEra and japanese.oldEra.eraYear and japanese.thisEra.article ~= japanese.oldEra.article then
			japanese.oldText = mw.ustring.format( '%s %d', japanese.oldEra.link, japanese.oldEra.eraYear )
			table.insert( japaneseYearText, japanese.oldText )
			table.insert( japaneseYearText, ' / ' )
		end
		if japanese.thisEra.eraYear then
			table.insert( japaneseYearText, mw.ustring.format( '%s %d', japanese.thisEra.link, japanese.thisEra.eraYear ) )
		end
		table.insert( japaneseYearText, mw.ustring.format( '<br /><small>(%s%s年)</small>', japanese.thisEra.kanji, japanese.thisEra.eraYearKanji ) )
		japanese:setYear( table.concat( japaneseYearText ) )
	end
 
	box:addCalendar( japanese )
 
	----------------------------------------------------------------------
	-- Julian calendar
	----------------------------------------------------------------------
 
	local julian = calendar:new()
	julian:setLink( 'گاه‌شماری ژولینی' )
 
	julian.yearVals = {
		{ 1901, 'میلادی منهای ۱۳ روز' },
		{ 1900, 'میلادی منهای ۱۲ یا ۱۳ روز'},
		{ 1801, 'میلادی منهای ۱۲ روز' },
		{ 1800, 'میلادی منهای ۱۱ یا ۱۲ روز' },
		{ 1701, 'میلادی منهای ۱۱ روز' },
		{ 1700, 'میلادی منهای ۱۰ یا ۱۱ روز' },
		{ 1582, 'میلادی منهای ۱۰ روز' },
		{ -45, gregorian.year }
	}
 
	for _, t in ipairs( julian.yearVals ) do
		if year >= t[ 1 ] then
			julian:setYear( t[ 2 ] )
			break
		end
	end
 
	box:addCalendar( julian )
 
	----------------------------------------------------------------------
	-- Burmese calendar
	----------------------------------------------------------------------
 
	local burmese = calendar:new()
	burmese:setLink( 'گاه‌شماری سنتی برمه‌ای' )
	burmese:setYear( year - 638 )
	box:addCalendar( burmese )
 
	----------------------------------------------------------------------
	-- Hebrew calendar
	----------------------------------------------------------------------
 
	local hebrew = calendar:new()
	hebrew:setLink( 'گاه‌شماری عبری' )
	hebrew:setYearRange( year + 3760, year + 3761 )
	box:addCalendar( hebrew )
 
	----------------------------------------------------------------------
	-- Coptic calendar
	----------------------------------------------------------------------
 
	local coptic = calendar:new()
	coptic:setLink( 'گاه‌شماری قبطی' )
	coptic:setYearRange( year - 284, year - 283 )
	box:addCalendar( coptic )
 
	----------------------------------------------------------------------
	-- Korean calendar
	----------------------------------------------------------------------
 
	local korean = calendar:new()
	korean:setLink( 'گاه‌شماری کره‌ای' )
	korean:setYear( year + 2333 )
	box:addCalendar( korean )
 
	----------------------------------------------------------------------
	-- Minguo calendar
	----------------------------------------------------------------------
 
	local minguo = calendar:new()
	minguo:setLink( 'گاه‌شماری مینگو' )
	if year > 1911 then
		local minguoYear = year - 1911
		minguo:setYear( mw.ustring.format( '[[تایوان|گاه‌شماری جمهوری چین]] %d<br /><small>民國%d年</small>', minguoYear, minguoYear ) )
	else
		local minguoYear = 1911 - year + 1
		minguo:setYear( mw.ustring.format( '%d پیش از [[جمهوری چین|گاه‌شماری جمهوری چین]]<br /><small>民前%d年</small>', minguoYear, minguoYear ) )
	end
	box:addCalendar( minguo )
 
	----------------------------------------------------------------------
	-- Holocene calendar
	----------------------------------------------------------------------
 
	local holocene = calendar:new()
	holocene:setLink( 'گاه‌شماری هولوسن' )
	holocene:setYear( year + 10000 )
	box:addCalendar( holocene )
 
	----------------------------------------------------------------------
	-- Hindu calendars
	----------------------------------------------------------------------
 
	local hindu = calendarGroup:new{ heading = '[[گاه‌شماری هندو|گاه‌شماری‌های هندو]]' }
 
	-- Vikram Samvat
 
	local vikramSamvat = calendar:new()
	vikramSamvat:setLink( 'ویکرم سموت' )
	vikramSamvat:setYearRange( year + 56, year + 57 )
	hindu:addCalendar( vikramSamvat )
 
	-- Shaka Samvat
 
	local shakaSamvat = calendar:new()
	shakaSamvat:setLink( 'گاه‌شماری ملی هند', 'شاکا ساموات' )
	if year - 76 > 0 then
		shakaSamvat:setYearRange( year - 78, year - 77 )
	end
	hindu:addCalendar( shakaSamvat )
 
	-- Kali Yuga
 
	local kaliYuga = calendar:new()
	kaliYuga:setLink( 'کالی یوگا' ) -- use italics
	kaliYuga:setYearRange( year + 3101, year + 3102 )
	hindu:addCalendar( kaliYuga )
 
	box:addCalendarGroup( hindu )
 
	----------------------------------------------------------------------
	-- Ab urbe condita
	----------------------------------------------------------------------
 
	local abUrbe = calendar:new()
	abUrbe:setLink( 'از تاریخ پیدایش رم (گاه‌شمار)', 'از تاریخ پیدایش رم' )
	abUrbe:setYear( year + 753 )
	box:addCalendar( abUrbe )
 
	----------------------------------------------------------------------
	-- Regnal year
	----------------------------------------------------------------------
 
	local regnal = calendar:new()
	local regnalName
	if year > 1706 then
		regnalName = 'بریتانیا'
	else
		regnalName = 'انگلیس'
	end
	regnal:setLink( 'سال‌های سلطنت پادشاهان انگلیس', 'سال سلطنت ' .. regnalName )
	regnal:setYear( getRegnal( year ) )
	box:addCalendar( regnal )
 
	----------------------------------------------------------------------
	-- Unix time
	----------------------------------------------------------------------
 
	local unix = calendar:new()
 
	local function getUnixTime( year )
		if year < 1970 then return end
		local noError, unixTime = pcall( lang.formatDate, lang, 'U', '1 Jan ' .. tostring( year ) )
		if not noError or noError and not unixTime then return end
		unixTime = tonumber( unixTime )
		if unixTime and unixTime >= 0 then
			return unixTime
		end
	end
 
	unix.thisYear = getUnixTime( year )
	unix.nextYear = getUnixTime( year + 1 )
	if unix.thisYear and unix.nextYear then
		unix:setLink( 'ساعت یونیکس' )
		unix:setYearRange( unix.thisYear, unix.nextYear - 1 )
	end
 
	box:addCalendar( unix )
 
	return box:export()
end
 
--------------------------------------------------------------------
-- Process arguments from #invoke
--------------------------------------------------------------------
 
local p = {}
 
function p.main( frame )
	-- Process the arguments and pass them to the box-building function.
	local args = getArgs( frame )
	-- خط زیر کمک می‌کند آرگومان سال را بدون نام پارامتر بتوان فرستاد.
	args.year = args.year or args[1]
	return makeCalendarBox( args )
end
 
return p