Module:Year in various calendars
This Lua module is used onapproximately 2,800 pagesand changes may be widely noticed. Test changes in the module's/sandboxor/testcasessubpages, or in your ownmodule sandbox.Consider discussing changes on thetalk pagebefore implementing them. |
This module is rated asbeta,and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected. |
This module depends on the following other modules: |
This module produces the sidebar opposite displaying a givenGregorianyear in various different calendars.
Syntax
Simple
{{#invoke:Year in various calendars|main}}
All parameters
{{#invoke:Year in various calendars|main |year=(n)|footnotes=(footnotes)|gregcal=(article name)}}
Parameters
- year
- Number specifying the year to be displayed. This can be negative and also can be in the format "n BC"to display BC dates or"AD n"as an alternative to a positive number. If not specified, the current year is used.
- footnotes
- Any footnotes to be placed at the bottom of the sidebar.
- gregcal
- Name of an article to be displayed for Gregorian and Julian years (e.g. "2000 BC" ). Do not include square brackets.
Microformat
- Classes used
TheHTML classesof this microformat include:
- attendee
- description
- dtend
- dtstart
- location
- summary
- url
- vevent
nor collapse nested elements which use them.
Adding new calendars
The module is set up to allow for easy addition of new calendars. Just scroll down to the "Build the box" section of the module code, and add your calendar as follows:
To display one year:
localmyCalendar=calendar:new()
myCalendar:setLink('My calendar article')-- The name of the calendar's Wikipedia article.
myCalendar:setYear(year+10)-- Lua code linking the Gregorian calendar year to your calendar's year.
box:addCalendar(myCalendar)
To display a year range:
localmyCalendar=calendar:new()
myCalendar:setLink('My calendar article')-- The name of the calendar's Wikipedia article.
myCalendar:setYearRange(year+10,year+11)-- Lua code outputting the start year and the end year of the year range.
box:addCalendar(myCalendar)
More complicated calendars can be passed as a string tocalendar:setYear()
.
Technical details
The module defines threeclasseswhich do the work of setting up the sidebar and displaying the data provided by the calendar functions. These are thecalendarBox
class, which defines the sidebar; thecalendar
class, which holds the data for one calendar; and thecalendarGroup
object, which defines a group of calendar objects with a heading.
To load these classes from another module, use the following:
localyearInOtherCalendars=require('Module:Year in various calendars')
localcalendarBox=yearInOtherCalendars.calendarBox
localcalendarGroup=yearInOtherCalendars.calendarGroup
localcalendar=yearInOtherCalendars.calendar
calendarBox class
AcalendarBox
object is initiated with:
local myCalendarBox = calendarBox:new{ year =yyyy,footnotes =footnotes,navbar =page name}
year
- sets the Gregorian year to base calendar calculations on. If not specified, the current year is used.footnotes
- sets text to be displayed in a footnotes section at the bottom of the sidebar.navbar
- sets the page name to be used by thenavbar.
Calendar box objects have the following properties:
calendarBox.year
- the Gregorian year number. This is negative for BC years; for example, for the year 100 BC the value of calendarBox.year is-99
.(BC years are calculated by "1 - n" rather than "0 - n", as there is no year zero.)calendarBox.yearText
- the Gregorian year text. This is a string value of the format "n" for AD years and "n BC" for BC years.calendarBox.caption
- the text of the box caption (the bold text that appears directly above the box). The default caption is the value ofcalendarBox.yearText
.calendarBox.footnotes
- the text of the box footnotes.calendarBox.navbar
- the page name used by the navbar.
Calendar box objects have the following methods:
calendarBox:setCaption(caption)
- sets the box caption (the bold text that appears directly above the box). The default caption is the value ofcalendarBox.yearText
.calendarBox:addCalendar(obj)
- adds a calendar object or a calendar group object to the calendar box.calendarBox:addCalendarGroup(obj)
- an alias formyCalendarBox:addCalendar()
.calendarBox:export()
- converts the calendar box object to wikicode. This callscalendar:export()
andcalendarGroup:export()
to export calendar objects and calendar group objects.
calendar class
Acalendar
object is initiated with:
local myCalendar = calendar:new()
Calendar objects have the following properties:
calendar.link
- the link name.calendar.year
- the year value. This is always a string value.
Calendar objects have the following methods:
calendar:setLink(link,display)
- sets the link name for the calendar object.link
is the name of Wikipedia's article about the calendar, anddisplay
is an optional display name for the article link.calendar:setRawLink(wikitext)
- sets the calendar link as raw wikitext.calendar:getLink()
- gets the link value.calendar:setYear(year)
- sets the year value for the calendar.year
can be a number or a string.calendar:setYearRange(startYear,endYear)
- sets the year value for the calendar as a year range. BothstartYear
andendYear
must be number values.calendar:export()
- exports the calendar to wikitext. If no link value was found, this returnsnil
.If a link was found but no year value was found, the calendar is output with a value ofN/A
for the year.
calendarGroup class
AcalendarGroup
object is initiated with:
local myCalendarGroup = calendarGroup:new{ heading =heading}
heading
- the wikitext heading for the calendar group (e.g.[[Hindu calendar]]s
).
Calendar group objects have one property:
calendarGroup.heading
- the calendar group heading text.
Calendar group objects have the following methods:
calendarGroup:addCalendar(obj)
- adds a calendar object to the calendar group.calendarGroup:export()
- converts a calendar group to wikitext. Callscalendar:export()
to export individual calendar objects.
See also
-- Load dependencies.
localgetArgs=require('Module:Arguments').getArgs
localnumToRoman=require('Module:Roman').main
localgetOlympiad=require('Module:Ancient Olympiads')._main
localgetDynasty=require('Module:Ancient Egypt era')._main
localgetPharaoh=require('Module:Ancient Egypt kings')._main
localnumToArmenian=require('Module:Armenian').main
localgetRegnal=require('Module:British regnal year').main
localjapaneseEra=require('Module:Japanese calendar').era()
-- Define constants.
locallang=mw.language.getContentLanguage()
localcurrentYear=tonumber(lang:formatDate('Y'))
--------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------
localfunctionisInteger(num)
-- Checks if a value is an integer. If so, returns the value converted to a number.
-- If not, returns false.
num=tonumber(num)
ifnumandmath.floor(num)==numandnum~=math.hugethen
returnnum
else
returnfalse
end
end
localfunctionBCToNum(s)
-- Converts strings of the format "n BC" to their corresponding
-- numerical values.
iftype(s)~='string'then
returnnil
end
s=mw.ustring.match(mw.ustring.upper(s),'^([1-9]%d*)%s*BC$')
ifnotsthen
returnnil
end
localnum=tonumber(s)
num=(num-1)*-1
returnnum
end
localfunctionnumToBC(num)
-- For BC years, returns a string with the year name appended with "BC".
-- Otherwise returns nil.
num=isInteger(num)
ifnotnumthenreturnend
ifnum<=0then
returnstring.format('%d BC',1-num)
end
end
localfunctionADToNum(s)
-- Converts strings of the format "AD n"
-- to their corresponding numerical values.
iftype(s)~='string'then
returnnil
end
s=mw.ustring.match(mw.ustring.upper(s),'^AD%s*([1-9]%d*)$')
ifnotsthen
returnnil
end
localnum=tonumber(s)
returnnum
end
localfunctionnumToAD(num)
-- For AD years up to 100, returns a string with the year name prepended with "AD".
-- Otherwise returns nil.
num=isInteger(num)
ifnotnumthenreturnend
if(num<=100)then
returnstring.format('AD %d',num)
end
end
localfunctionformatNegative(s)
-- Replaces hyphens in a string with minus signs if the hyphen comes before a number.
s=mw.ustring.gsub(s,'%-(%d)','−%1')
returns
end
--------------------------------------------------------------------
-- Calendar box class definition
--------------------------------------------------------------------
localcalendarBox={}
calendarBox.__index=calendarBox
functioncalendarBox:new(init)
init=type(init)=='table'andinitor{}
localobj={}
localpagename=mw.title.getCurrentTitle().text
-- 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.
localyearNum=isInteger(init.year)
localyearBC=BCToNum(init.year)
localyearAD=ADToNum(init.year)
localpageNum=isInteger(pagename)
localpageBC=BCToNum(pagename)
localpageAD=ADToNum(pagename)
ifyearNumthen-- First, see if the year parameter is a number.
self.year=yearNum
elseifyearBCthen-- Second, see if the year parameter is a "yyyy BC" string.
self.year=yearBC
elseifyearADthen-- Third, see if the year parameter is an AD/CE/year string.
self.year=yearAD
elseifpageNumthen-- Fourth, see if the pagename is an integer.
self.year=pageNum
elseifpageBCthen-- Fifth, see if the pagename is a "yyyy BC" string.
self.year=pageBC
elseifpageADthen-- Sixth, see if the pagename is an AD/CE/year string.
self.year=pageAD
else
self.year=currentYear-- If none of the above apply, use the current year.
end
-- Set year text values.
self.BCYearName=numToBC(self.year)
self.ADYearName=numToAD(self.year)
ifself.BCYearNamethen
self.yearText=self.BCYearName
elseifself.ADYearNamethen
self.yearText=self.ADYearName
else
self.yearText=tostring(self.year)
end
-- Set other fields.
self.caption=self.yearText
self.footnotes=init.footnotes
returnsetmetatable(obj,{
__index=self
})
end
functioncalendarBox:setCaption(s)
-- Sets the calendar box caption.
iftype(s)~='string'ors==''thenreturnend
self.caption=s
end
functioncalendarBox:addCalendar(obj)
-- Adds a calendar or a calendar group.
iftype(obj)~='table'andtype(obj.new)~='function'thenreturnend-- Exit if the object is invalid.
self.calendars=self.calendarsor{}
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
functioncalendarBox:export()
-- Outputs the calendar box wikitext.
localroot=mw.html.create('table')
-- Export the calendar box headers.
root
:addClass('infobox vevent')
:css('width','22em')
:tag('caption')
:css('font-size','125%')
:tag('span')
:addClass('summary 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.
iftype(self.calendars)=='table'then
for_,calendarinipairs(self.calendars)do
localcalendarText=calendar:export()
iftype(calendarText)=='string'then
root:wikitext(calendarText)
end
end
end
-- Add footnotes.
iftype(self.footnotes)=='string'andself.footnotes~=''then
root
:tag('tr')
:tag('td')
:attr('colspan','2')
:wikitext(string.format('%s',self.footnotes))
end
returntostring(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.
localcalendarGroup={}
calendarGroup.__index=calendarGroup
functioncalendarGroup:new(init)
init=type(init)=='table'andinitor{}
localobj={}
-- Get the heading and throw an error if it is invalid.
obj.heading=init.heading
iftype(obj.heading)~='string'then
error('calendarGroup: no heading detected')
end
-- Set the metatable and return the object.
self.__index=self
returnsetmetatable(obj,{
__index=self
})
end
functioncalendarGroup:addCalendar(calendar)
-- Adds a calendar object to the calendar group.
self.calendars=self.calendarsor{}
iftype(calendar)=='table'andtype(calendar.getLink)=='function'then
table.insert(self.calendars,calendar)
end
end
functioncalendarGroup:export()
-- Exports the calendar group's wikitext.
-- Indent and italicise each calendar's link if it exists.
fori,calendarinipairs(self.calendars)do
locallink=calendar:getLink()
iftype(link)=='string'then
self.calendars[i]:setRawLink(string.format(" - ''%s''",link))
end
end
-- Create the heading row html and export the calendar objects.
localret=mw.html.create()
ret
:tag('tr')
:tag('td')
:wikitext(self.heading)
:done()
:tag('td')-- Use a blank tag to make the html look nice.
:allDone()
for_,calendarinipairs(self.calendars)do
ret:wikitext(calendar:export())
end
returntostring(ret)
end
--------------------------------------------------------------------
-- Calendar class definition
--------------------------------------------------------------------
localcalendar={}
calendar.__index=calendar
calendar.type='calendar'
functioncalendar:new()
localobj={}
returnsetmetatable(obj,{
__index=self
})
end
functioncalendar:setLink(link,display)
-- Sets the calendar's wikilink, with optional display text and italics.
iftype(link)~='string'orlink==''thenreturnend
display=type(display)=='string'anddisplay~=''anddisplay
ifdisplaythen
self.link=string.format('[[%s|%s]]',link,display)
else
self.link=string.format('[[%s]]',link)
end
end
functioncalendar:setRawLink(s)
-- Sets the calendar's wikilink as raw wikitext.
iftype(s)~='string'ors==''thenreturnend
self.link=s
end
functioncalendar:getLink()
-- Returns the calendar's link value.
returnself.link
end
functioncalendar: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.
iftype(year)=='number'then
year=tostring(year)
self.year=formatNegative(year)
elseiftype(year)=='string'then
self.year=year
end
end
functioncalendar:setYearRange(year1,year2)
-- Sets a year range. Must be passed two numbers.
iftype(year1)=='number'andtype(year2)=='number'then
localyear
ifyear1<0oryear2<0then-- Leave a gap for negative years to avoid having a minus sign and a dash right next to each other.
year=string.format('%d – %d',year1,year2)
year=formatNegative(year)
else
year=string.format('%d–%d',year1,year2)
end
self.year=year
end
end
functioncalendar:setYearCouple(year1,year2,addtext)
-- Same as setYearRange, only with a slash (/) in the middle. Must be passed two numbers.
-- Additional text possible, must be defined as follows: addtext = string.format( 'additional text or link')
-- See example in Seleucid era calendar
iftype(year1)=='number'andtype(year2)=='number'then
localyear
ifyear1<0oryear2<0then-- Leave no gap for negative years.
year=string.format('%d/%d %s',year1,year2,addtext)
year=formatNegative(year)
else
year=string.format('%d/%d %s',year1,year2,addtext)
end
self.year=year
end
end
functioncalendar:export()
-- Outputs the calendar wikitext.
-- Exit if no link has been specified.
locallink=self.link
iftype(link)~='string'orlink==''thenreturnend
-- If no year has been specified, set the year value to N/A.
localyear=self.year
iftype(year)~='string'oryear==''then
year="''N/A''"
end
-- Build the table row.
localret=mw.html.create()
ret
:tag('tr')
:tag('td')
:wikitext(link)
:done()
:tag('td')
:wikitext(year)
:allDone()
returntostring(ret)
end
--------------------------------------------------------------------
-- Build the box
--------------------------------------------------------------------
localfunctionmakeCalendarBox(args)
-- Initiate the box and get the year values.
localinit=args
localbox=calendarBox:new(init)
localyear=box.year
localyearText=box.yearText
-- Set the caption.
box:setCaption(box.caption..' in various [[Calendar era|calendars]]')
----------------------------------------------------------------------
-- Gregorian calendar
----------------------------------------------------------------------
localgregorian=calendar:new()
gregorian:setLink('Gregorian calendar')
-- Get the year link.
localgregcal=args.gregcal
iftype(gregcal)=='string'andgregcal~=''then
gregorian.yearLink=string.format('[[%s|%s]]',gregcal,yearText)
else
gregorian.yearLink=yearText
end
-- Set the year.
ifyear<=0then
gregorian.romanYear=numToRoman{-(year-1)}..' BC'
else
gregorian.romanYear=numToRoman{year}
end
ifgregorian.romanYearthen
gregorian:setYear(string.format(
[[%s<br /><span style= "font-family: serif;" >''%s''</span>]],
gregorian.yearLink,gregorian.romanYear
))
else
gregorian:setYear(gregorian.yearLink)
end
box:addCalendar(gregorian)
----------------------------------------------------------------------
-- French Republican calendar
-- displays only in years 1793 - 1805 and 1871
-- This calendar was in use and had defined years only for the short period on display.
-- Its importance during these few years is also the reason why it should stay out of the alphabetic order.
-- See discussion on talk page.
----------------------------------------------------------------------
ifyear>=1793andyear<1806oryear==1871then
localrepublican=calendar:new()
republican:setLink('French Republican calendar')
ifyear<=1870then
republican:setYearRange(year-1792,year-1791)
elseifyear==1871then
republican:setYear(year-1792)-- Paris Commune, May
end
box:addCalendar(republican)
end
----------------------------------------------------------------------
-- Ab urbe condita
-- Varro's correlation, from 1 AUC
----------------------------------------------------------------------
ifyear>=-752then
localabUrbe=calendar:new()
abUrbe:setLink('Ab urbe condita')
abUrbe:setYear(year+753)
box:addCalendar(abUrbe)
end
----------------------------------------------------------------------
-- Ancient Egypt era
-- Displays dynasty between 1549 BC and 30 BC
-- Displays pharaoh or king between 752 BC and 30 BC
----------------------------------------------------------------------
ifyear>-1549andyear<=-29then
localancEgypt=calendar:new()
ancEgypt:setLink(
'Egyptian chronology',
'Ancient Egypt era'
)
ancEgypt:setYear(getDynasty(year))
box:addCalendar(ancEgypt)
end
ifyear>-752andyear<=-29then
localancPharaoh=calendar:new()
ancPharaoh:setLink(
'List of pharaohs',
'<i>- Pharaoh</i>'
)
ancPharaoh:setYear(getPharaoh(year))
box:addCalendar(ancPharaoh)
end
----------------------------------------------------------------------
-- Ancient Olympiads
-- Currently only the first 194 Olympiads
-- May be expanded until 394 AD when data available
----------------------------------------------------------------------
ifyear>=-1300andyear<1then
localancOlympiads=calendar:new()
ancOlympiads:setLink(
'Ancient Greek calendar',
'Ancient Greek era'
)
ancOlympiads:setYear(getOlympiad(year))
box:addCalendar(ancOlympiads)
end
----------------------------------------------------------------------
-- Armenian calendar
----------------------------------------------------------------------
ifyear>551then
localarmenian=calendar:new()
armenian:setLink('Armenian calendar')
localarmenianYear=year-551
armenian:setYear(string.format('%s<br />ԹՎ %s',armenianYear,numToArmenian(armenianYear)))
box:addCalendar(armenian)
end
----------------------------------------------------------------------
-- Assyrian calendar
----------------------------------------------------------------------
localassyrian=calendar:new()
assyrian:setLink('Assyrian calendar')
assyrian:setYear(year+4750)
box:addCalendar(assyrian)
----------------------------------------------------------------------
-- Bahá'í calendar
-- displays only after 1843
----------------------------------------------------------------------
ifyear>=1844then
localbahai=calendar:new()
bahai:setLink("Baháʼí calendar")
bahai:setYearRange(year-1844,year-1843)
box:addCalendar(bahai)
end
----------------------------------------------------------------------
-- Balinese saka calendar
----------------------------------------------------------------------
localbalinese=calendar:new()
balinese:setLink('Balinese saka calendar')
ifyear-76>0then
balinese:setYearRange(year-79,year-78)
end
box:addCalendar(balinese)
----------------------------------------------------------------------
-- Bengali calendar
----------------------------------------------------------------------
localbengali=calendar:new()
bengali:setLink('Bengali calendar')
bengali:setYear(year-593)
box:addCalendar(bengali)
----------------------------------------------------------------------
-- Berber calendar
----------------------------------------------------------------------
localberber=calendar:new()
berber:setLink('Berber calendar')
berber:setYear(year+950)
box:addCalendar(berber)
----------------------------------------------------------------------
-- Regnal year
----------------------------------------------------------------------
ifyear>=1000then
localregnal=calendar:new()
localregnalName
ifyear>1706then
regnalName='British'
else
regnalName='English'
end
regnal:setLink('Regnal years of English and British monarchs',regnalName..' Regnal year')
regnal:setYear(getRegnal(year))
box:addCalendar(regnal)
end
----------------------------------------------------------------------
-- Buddhist calendar
----------------------------------------------------------------------
localbuddhist=calendar:new()
buddhist:setLink('Buddhist calendar')
buddhist:setYear(year+544)
box:addCalendar(buddhist)
----------------------------------------------------------------------
-- Burmese calendar
----------------------------------------------------------------------
localburmese=calendar:new()
burmese:setLink('Burmese calendar')
burmese:setYear(year-638)
box:addCalendar(burmese)
----------------------------------------------------------------------
-- Byzantine calendar
----------------------------------------------------------------------
localbyzantine=calendar:new()
byzantine:setLink('Byzantine calendar')
byzantine:setYearRange(year+5508,year+5509)
box:addCalendar(byzantine)
----------------------------------------------------------------------
-- Chinese calendar
----------------------------------------------------------------------
localchinese=calendar:new()
chinese:setLink('Chinese calendar')
-- Define the information for the "heavenly stems" and "earthly branches" year cycles.
-- See [[Chinese calendar#Cycle of years]] for information.
localheavenlyStems={
{' giáp ','Wood'},-- 1
{' ất ','Wood'},-- 2
{' bính ','Fire'},-- 3
{' đinh ','Fire'},-- 4
{' mậu ','Earth'},-- 5
{' kỷ ','Earth'},-- 6
{' canh ','Metal'},-- 7
{' tân ','Metal'},-- 8
{' nhâm ','Water'},-- 9
{' quý ','Water'}-- 10
}
localearthlyBranches={
{' tử ','[[Rat (zodiac)|Rat]]'},-- 1
{' sửu ','[[Ox (zodiac)|Ox]]'},-- 2
{' dần ','[[Tiger (zodiac)|Tiger]]'},-- 3
{' mão ','[[Rabbit (zodiac)|Rabbit]]'},-- 4
{' thần ','[[Dragon (zodiac)|Dragon]]'},-- 5
{' tị ','[[Snake (zodiac)|Snake]]'},-- 6
{' ngọ ','[[Horse (zodiac)|Horse]]'},-- 7
{' vị ','[[Goat (zodiac)|Goat]]'},-- 8
{' thân ','[[Monkey (zodiac)|Monkey]]'},-- 9
{' dậu ','[[Rooster (zodiac)|Rooster]]'},-- 10
{' tuất ','[[Dog (zodiac)|Dog]]'},-- 11
{' hợi ','[[Pig (zodiac)|Pig]]'}-- 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.
localsexagenaryYear1=(year-4)%60
localsexagenaryYear2=(year-3)%60
localheavenlyNum1=(sexagenaryYear1-1)%10+1-- amod, since lua arrays are 1-indexed
localheavenlyNum2=(sexagenaryYear2-1)%10+1
localearthlyNum1=(sexagenaryYear1-1)%12+1
localearthlyNum2=(sexagenaryYear2-1)%12+1
-- Get the data tables for each permutation.
localheavenlyTable1=heavenlyStems[heavenlyNum1]
localheavenlyTable2=heavenlyStems[heavenlyNum2]
localearthlyTable1=earthlyBranches[earthlyNum1]
localearthlyTable2=earthlyBranches[earthlyNum2]
-- Work out the continously-numbered year. (See [[Chinese calendar#Continuously numbered years]].)
localyear1=year+2697
localyear2=year+2698
localyear1Alt=year1-207
localyear2Alt=year2-207
-- 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(string.format(
[=[[[Sexagenary cycle|%s%s]] niên (%s %s)<br />%s or %s<br /> ''— to —''<br />%s%s niên (%s %s)<br />%s or %s]=],
heavenlyTable1[1],
earthlyTable1[1],
heavenlyTable1[2],
earthlyTable1[2],
year1,
year1Alt,
heavenlyTable2[1],
earthlyTable2[1],
heavenlyTable2[2],
earthlyTable2[2],
year2,
year2Alt
))
box:addCalendar(chinese)
----------------------------------------------------------------------
-- Coptic calendar
----------------------------------------------------------------------
localcoptic=calendar:new()
coptic:setLink('Coptic calendar')
coptic:setYearRange(year-284,year-283)
box:addCalendar(coptic)
----------------------------------------------------------------------
-- Discordian calendar
----------------------------------------------------------------------
localdiscordian=calendar:new()
discordian:setLink('Discordian calendar')
discordian:setYear(year+1166)
box:addCalendar(discordian)
----------------------------------------------------------------------
-- Ethiopian calendar
----------------------------------------------------------------------
localethiopian=calendar:new()
ethiopian:setLink('Ethiopian calendar')
ethiopian:setYearRange(year-8,year-7)
box:addCalendar(ethiopian)
----------------------------------------------------------------------
-- Hebrew calendar
----------------------------------------------------------------------
localhebrew=calendar:new()
hebrew:setLink('Hebrew calendar')
hebrew:setYearRange(year+3760,year+3761)
box:addCalendar(hebrew)
----------------------------------------------------------------------
-- Hindu calendars
----------------------------------------------------------------------
localhindu=calendarGroup:new{heading='[[Hindu calendar]]s'}
-- Vikram Samvat
localvikramSamvat=calendar:new()
vikramSamvat:setLink('Vikram Samvat')
vikramSamvat:setYearRange(year+56,year+57)
hindu:addCalendar(vikramSamvat)
-- Shaka Samvat
localshakaSamvat=calendar:new()
shakaSamvat:setLink('Indian national calendar','Shaka Samvat')
ifyear>=78then
shakaSamvat:setYearRange(year-79,year-78)
end
hindu:addCalendar(shakaSamvat)
-- Kali Yuga
localkaliYuga=calendar:new()
kaliYuga:setLink('Kali Yuga')-- use italics
kaliYuga:setYearRange(year+3100,year+3101)
hindu:addCalendar(kaliYuga)
box:addCalendarGroup(hindu)
----------------------------------------------------------------------
-- Holocene calendar
----------------------------------------------------------------------
localholocene=calendar:new()
holocene:setLink('Holocene calendar')
holocene:setYear(year+10000)
box:addCalendar(holocene)
----------------------------------------------------------------------
-- 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.
ifyear>=1000then
localigbo=calendar:new()
igbo:setLink('Igbo calendar')
igbo:setYearRange(year-1000,year-999)
box:addCalendar(igbo)
end
----------------------------------------------------------------------
-- Iranian calendar
----------------------------------------------------------------------
localiranian=calendar:new()
iranian:setLink('Iranian calendars','Iranian calendar')
ifyear-621>0then
iranian:setYearRange(year-622,year-621)
else
iranian:setYear(string.format('%d BP – %d BP',622-year,621-year))
end
box:addCalendar(iranian)
----------------------------------------------------------------------
-- Islamic calendar
----------------------------------------------------------------------
localislamic=calendar:new()
islamic:setLink('Islamic calendar')
localislamicMult=1.030684-- the factor to multiply by
localislamicSub=621.5643-- the factor to subtract by
ifyear-621>0then
localyear1=math.floor(islamicMult*(year-islamicSub))
localyear2=math.floor(islamicMult*(year-islamicSub+1))
islamic:setYearRange(year1,year2)
else
localyear1=math.ceil(-islamicMult*(year-islamicSub))
localyear2=math.ceil(-islamicMult*(year-islamicSub+1))
islamic:setYear(string.format('%d BH – %d BH',year1,year2))
end
box:addCalendar(islamic)
----------------------------------------------------------------------
-- Japanese calendar
-- starting 600
----------------------------------------------------------------------
ifyear>=600then
localjapanese=calendar:new()
japanese:setLink('Japanese calendar')
japanese.thisEra=japaneseEra:new{year=year}
ifjapanese.thisErathen
localjapaneseYearText={}
japanese.oldEra=japanese.thisEra:getOldEra()
ifjapanese.oldEraandjapanese.oldEra.eraYearandjapanese.thisEra.article~=japanese.oldEra.articlethen
japanese.oldText=string.format('%s %d',japanese.oldEra.link,japanese.oldEra.eraYear)
table.insert(japaneseYearText,japanese.oldText)
table.insert(japaneseYearText,' / ')
end
ifjapanese.thisEra.eraYearthen
table.insert(japaneseYearText,string.format('%s %d',japanese.thisEra.link,japanese.thisEra.eraYear))
end
table.insert(japaneseYearText,string.format('<br />(%s%s niên )',japanese.thisEra.kanji,japanese.thisEra.eraYearKanji))
japanese:setYear(table.concat(japaneseYearText))
end
box:addCalendar(japanese)
end
----------------------------------------------------------------------
-- Javanese calendar
----------------------------------------------------------------------
localjavanese=calendar:new()
javanese:setLink('Javanese calendar')
localjavaneseMult=1.030684-- the factor to multiply by
localjavaneseSub=124.9-- the factor to subtract by
ifyear-124>0then
localyear1=math.floor(javaneseMult*(year-javaneseSub))
localyear2=math.floor(javaneseMult*(year-javaneseSub+1))
javanese:setYearRange(year1,year2)
else
localyear1=math.ceil(-javaneseMult*(year-javaneseSub))
localyear2=math.ceil(-javaneseMult*(year-javaneseSub+1))
end
box:addCalendar(javanese)
----------------------------------------------------------------------
-- Juche calendar
-- displays only after 1910
----------------------------------------------------------------------
ifyear>=1910then
localjuche=calendar:new()
juche:setLink('Juche calendar')
ifyear>1911then
juche:setYear(year-1911)
end
box:addCalendar(juche)
end
----------------------------------------------------------------------
-- Julian calendar
----------------------------------------------------------------------
localjulian=calendar:new()
julian:setLink('Julian calendar')
ifyear>=-45andyear<1582then
julian:setYear(gregorian.year)
elseifyear>=1582then
localdiff=math.floor(year/100-2)-math.floor(year/400)
ifyear%100==0andyear%400~=0then
julian:setYear('Gregorian minus '..diff-1..' or '..diff..' days')
else
julian:setYear('Gregorian minus '..diff..' days')
end
end
box:addCalendar(julian)
----------------------------------------------------------------------
-- Korean calendar
----------------------------------------------------------------------
localkorean=calendar:new()
korean:setLink('Korean calendar')
korean:setYear(year+2333)
box:addCalendar(korean)
----------------------------------------------------------------------
-- Minguo calendar
----------------------------------------------------------------------
localminguo=calendar:new()
minguo:setLink('Minguo calendar')
ifyear>1949then
localminguoYear=year-1911
minguo:setYear(string.format('[[Taiwan|ROC]] %d<br /> dân quốc %d niên ',minguoYear,minguoYear))
elseifyear>1911then
localminguoYear=year-1911
minguo:setYear(string.format('[[Republic of China (1912–1949)|ROC]] %d<br /> dân quốc %d niên ',minguoYear,minguoYear))
else
localminguoYear=1911-year+1
minguo:setYear(string.format('%d before [[Republic of China (1912–1949)|ROC]]<br /> dân tiền %d niên ',minguoYear,minguoYear))
end
box:addCalendar(minguo)
----------------------------------------------------------------------
-- Nanakshahi calendar
----------------------------------------------------------------------
localnanakshahi=calendar:new()
nanakshahi:setLink('Nanakshahi calendar')
nanakshahi:setYear(year-1468)
box:addCalendar(nanakshahi)
----------------------------------------------------------------------
-- Seleucid era
-- displays from 312 BC until 1200 AD
----------------------------------------------------------------------
ifyear>=-311andyear<1200then
localseleucid=calendar:new()
seleucid:setLink('Seleucid era')
localaddtext=string.format('[[Anno Graecorum|AG]]')
seleucid:setYearCouple(year+311,year+312,addtext)
box:addCalendar(seleucid)
end
----------------------------------------------------------------------
-- Thai solar calendar
----------------------------------------------------------------------
localthai=calendar:new()
thai:setLink('Thai solar calendar')
ifyear>=1941then
thai:setYear(year+543)
else-- if year >= 1912 or year <= 1887 -- year started in March/April
thai:setYearRange(year+542,year+543)
-- else -- Rattanakosin Era, 1888?-1912
-- thai:setYear( string.format( '%d – %d ([[Rattanakosin Kingdom|Rattanakosin Era]])', year - 1782, year - 1781 ) )
end
box:addCalendar(thai)
----------------------------------------------------------------------
-- Tibetan calendar
----------------------------------------------------------------------
localtibetan=calendar:new()
tibetan:setLink('Tibetan calendar')
-- Define the information for the "heavenly stems" and "earthly branches" year cycles.
-- See [[Tibetan calendar#Years]] for information.
localheavenlyStems={
{' dương mộc ','male Wood'},-- 1
{' âm mộc ','female Wood'},-- 2
{' dương hỏa ','male Fire'},-- 3
{' âm hỏa ','female Fire'},-- 4
{' dương thổ ','male Earth'},-- 5
{' âm thổ ','female Earth'},-- 6
{' dương kim ','male Iron'},-- 7
{' âm kim ','female Iron'},-- 8
{' dương thủy ','male Water'},-- 9
{' âm thủy ','female Water'}-- 10
}
localearthlyBranches={
{' thử ','[[Rat (zodiac)|Rat]]'},-- 1
{' ngưu ','[[Ox (zodiac)|Ox]]'},-- 2
{' hổ ','[[Tiger (zodiac)|Tiger]]'},-- 3
{' thỏ ','[[Rabbit (zodiac)|Rabbit]]'},-- 4
{' long ','[[Dragon (zodiac)|Dragon]]'},-- 5
{' xà ','[[Snake (zodiac)|Snake]]'},-- 6
{' mã ','[[Horse (zodiac)|Horse]]'},-- 7
{' dương ','[[Goat (zodiac)|Goat]]'},-- 8
{' hầu ','[[Monkey (zodiac)|Monkey]]'},-- 9
{' kê ','[[Rooster (zodiac)|Rooster]]'},-- 10
{' cẩu ','[[Dog (zodiac)|Dog]]'},-- 11
{' trư ','[[Pig (zodiac)|Pig]]'}-- 12
}
-- Calculate the cycle numbers from the year. The first sexagenary year corresponds to the ''previous'' year's entry
-- in [[Tibetan calendar correspondence table]], as the Tibetan New Year doesn't happen until Feb/Mar in
-- Gregorian years.
localsexagenaryYear1=(year-4)%60
localsexagenaryYear2=(year-3)%60
localheavenlyNum1=(sexagenaryYear1-1)%10+1-- amod, since lua arrays are 1-indexed
localheavenlyNum2=(sexagenaryYear2-1)%10+1
localearthlyNum1=(sexagenaryYear1-1)%12+1
localearthlyNum2=(sexagenaryYear2-1)%12+1
-- Get the data tables for each permutation.
localheavenlyTable1=heavenlyStems[heavenlyNum1]
localheavenlyTable2=heavenlyStems[heavenlyNum2]
localearthlyTable1=earthlyBranches[earthlyNum1]
localearthlyTable2=earthlyBranches[earthlyNum2]
-- Work out the continously-numbered year. (See [[Tibetan calendar#Years with cardinal numbers]].)
localyear1=year+126
localyear2=year+127
localyear1Alt1=year1-381
localyear1Alt2=year1-1153
localyear2Alt1=year2-381
localyear2Alt2=year2-1153
-- Format any negative numbers.
year1=formatNegative(tostring(year1))
year2=formatNegative(tostring(year2))
year1Alt1=formatNegative(tostring(year1Alt1))
year1Alt2=formatNegative(tostring(year1Alt2))
year2Alt1=formatNegative(tostring(year2Alt1))
year2Alt2=formatNegative(tostring(year2Alt2))
-- Return all of that data in a (hopefully) reader-friendly format.
tibetan:setYear(string.format(
[=[%s%s niên <br />(%s-%s)<br />%s or %s or %s<br /> ''— to —''<br />%s%s niên <br />(%s-%s)<br />%s or %s or %s]=],
heavenlyTable1[1],
earthlyTable1[1],
heavenlyTable1[2],
earthlyTable1[2],
year1,
year1Alt1,
year1Alt2,
heavenlyTable2[1],
earthlyTable2[1],
heavenlyTable2[2],
earthlyTable2[2],
year2,
year2Alt1,
year2Alt2
))
box:addCalendar(tibetan)
----------------------------------------------------------------------
-- Unix time
----------------------------------------------------------------------
localunix=calendar:new()
localfunctiongetUnixTime(year)
ifyear<1970thenreturnend
localnoError,unixTime=pcall(lang.formatDate,lang,'U','1 Jan '..tostring(year))
ifnotnoErrorornoErrorandnotunixTimethenreturnend
unixTime=tonumber(unixTime)
ifunixTimeandunixTime>=0then
returnunixTime-1
end
end
unix.thisYear=getUnixTime(year)
unix.nextYear=getUnixTime(year+1)
ifunix.thisYearandunix.nextYearthen
unix:setLink('Unix time')
unix:setYear((unix.thisYear+1).."–"..unix.nextYear)
end
box:addCalendar(unix)
returnbox:export()
end
--------------------------------------------------------------------
-- Process arguments from #invoke
--------------------------------------------------------------------
localp={}
functionp.main(frame)
-- Process the arguments and pass them to the box-building function.
localargs=getArgs(frame)
-- Pass year argument with 'year' parameter or without any name but first argument
args.year=args.yearorargs[1]
returnmakeCalendarBox(args)
end
returnp