| Modul ini dilindungi. Modul ini sangat mencolok yang digunakan oleh banyak halaman, atau sangat sering disubstitusikan. Karena vandalisme atau kesalahan akan mempengaruhi banyak halaman, dan suntingan kecil dapat memberi beban besar pada server, modul ini dilindungi dari penyuntingan. |
| Modul Lua ini digunakan pada sekitar 4.200 halaman dan perubahannya kemungkinan memicu perubahan massal pada semua halaman yang menggunakannya. Uji cobalah di subhalaman /bak pasir atau /kasus uji Modul:Age, atau bak pasir modul Anda. Pertimbangkan untuk mendiskusikan perubahan di halaman pembicaraan sebelum mengimplementasikannya. |
Templates supportedTemplates supported
Module:Age implements the following templates:
| Template | Required wikitext |
|---|---|
| {{extract}} | {{#invoke:age|extract}}
|
| {{gregorian serial date}} | {{#invoke:age|gsd}}
|
| {{time interval}} | {{#invoke:age|time_interval}}
|
| {{age in days}} | {{#invoke:age|age_generic|template=age_days}}
|
| {{age in days nts}} | {{#invoke:age|age_generic|template=age_days_nts}}
|
| {{duration in days}} | {{#invoke:age|age_generic|template=duration_days}}
|
| {{duration in days nts}} | {{#invoke:age|age_generic|template=duration_days_nts}}
|
| {{age}} | {{#invoke:age|age_generic|template=age_full_years}}
|
| {{age nts}} | {{#invoke:age|age_generic|template=age_full_years_nts}}
|
| {{age in years}} | {{#invoke:age|age_generic|template=age_in_years}}
|
| {{age in years nts}} | {{#invoke:age|age_generic|template=age_in_years_nts}}
|
| {{age for infant}} | {{#invoke:age|age_generic|template=age_infant}}
|
| {{age in months}} | {{#invoke:age|age_generic|template=age_m}}
|
| {{age in weeks}} | {{#invoke:age|age_generic|template=age_w}}
|
| {{age in weeks and days}} | {{#invoke:age|age_generic|template=age_wd}}
|
| {{age in years and days}} | {{#invoke:age|age_generic|template=age_yd}}
|
| {{age in years and days nts}} | {{#invoke:age|age_generic|template=age_yd_nts}}
|
| {{age in years and months}} | {{#invoke:age|age_generic|template=age_ym}}
|
| {{age in years, months and days}} | {{#invoke:age|age_generic|template=age_ymd}}
|
| {{age in years, months, weeks and days}} | {{#invoke:age|age_generic|template=age_ymwd}}
|
| {{birth date and age}} | {{#invoke:age|birth_date_and_age}}
|
| {{death date and age}} | {{#invoke:age|death_date_and_age}}
|
Redirects
| Template | Redirects to |
|---|---|
| {{hla}} | {{age in years, months and days}} |
| {{age in months, weeks and days}} | {{age in years, months, weeks and days}} |
| {{bda}} | {{birth date and age}} |
| {{dda}} | {{death date and age}} |
| {{gsd}} | {{gregorian serial date}} |
The age templates expect the older date to be first. The implementations of age_in_years and age_in_years_nts display an error message if that is not the case. If similar checking is wanted for other templates, negative=error can be added to the invoke. For example, {{age}} might use:
{{#invoke:age|age_generic|template=age_full_years|negative=error}}
If negative=error does not apply, a negative difference is indicated with a minus sign (−).
Date formatsDate formats
Dates can use numbered or named parameters to specify year/month/day. Alternatively, a full date can be entered in a variety of formats. For example:
{{age in years and months|year1=2001|month1=1|day1=10|year2=2012|month2=2|day2=20}}→ 11 tahun, 1 bulan{{age in years and months|year=2001|month=1|day=10|year2=2012|month2=2|day2=20}}→ 11 tahun, 1 bulan{{age in years and months|2001|1|10|2012|2|20}}→ 11 tahun, 1 bulan{{age in years and months|2001-1-10|2012-2-20}}→ 11 tahun, 1 bulan{{age in years and months|10 Jan 2001|20 Feb 2012}}→ 11 tahun, 1 bulan{{age in years and months|January 10, 2001|Feb 20, 2012}}→ 11 tahun, 1 bulan
If the first or second date is omitted, the current date is used. For example:
{{age in years and months|year2=2012|month2=2|day2=20}}→ −14 tahun, 8 bulan{{age in years and months||||2012|2|20}}→ −14 tahun, 8 bulan{{age in years and months||2012-2-20}}→ −14 tahun, 8 bulan{{age in years and months||20 Feb 2012}}→ −14 tahun, 8 bulan{{age in years and months||Feb 20, 2012}}→ −14 tahun, 8 bulan{{age in years and months|year1=2001|month1=1|day1=10}}→ 25 tahun, 9 bulan{{age in years and months|year=2001|month=1|day=10}}→ 25 tahun, 9 bulan{{age in years and months|2001|1|10}}→ 25 tahun, 9 bulan{{age in years and months|2001-1-10}}→ 25 tahun, 9 bulan{{age in years and months|10 Jan 2001}}→ 25 tahun, 9 bulan{{age in years and months|January 10, 2001}}→ 25 tahun, 9 bulan
ParametersParameters
The following options are available:
| Parameter | Description |
|---|---|
duration=on |
The finishing date is included in the result; that adds one day to the age. |
fix=on |
Adjust invalid time units. See Template:Extract#Fix. |
format=commas |
A value of 1,000 or more is displayed with commas. |
format=raw |
Numbers are displayed without commas and negative numbers are displayed with a hyphen for {{#expr}}. In addition, {{age}} outputs a plain number and will not include a span to indicate if the result relies on the current date.
|
format=cardinal |
Display the resulting number using words such as "five" instead of 5. See below. |
format=ordinal |
Display the resulting number using words such as "fifth" instead of 5. See below. |
range=dash |
Accept a year only, or a year and month only, and show a range of ages with an en dash (–). |
range=yes |
Accept a year or year/month, and show the range with "or". |
range=no |
Accept a year only, or year/month, but show only a single age as if full dates had been entered. |
round=on |
The age is rounded to the nearest least-significant time unit. |
sc=on |
A serial comma is used (only useful when three or more values are displayed). |
sc=yes |
Same as sc=on.
|
show=hide |
The age is not displayed; may be useful with sortable=on.
|
sortable=on |
Insert a hidden sort key before the result (for use in sortable tables). |
sortable=table |
Insert a sort key using table syntax data-sort-value="value"|.
|
sortable=debug |
Same as sortable=on but the sort key is displayed for testing.
|
sortable=off |
No sort key (can override the default for a template like {{age nts}}). |
Examples using the range parameter follow.
{{age in years and months|year=2001|month=1|year2=2012|month2=2|range=yes}}→ 11 tahun, 0 atau 1 bulan{{age in years and months|2001|1||2012|2|range=yes}}→ 11 tahun, 0 atau 1 bulan{{age in years and months|Jan 2001|Feb 2012|range=yes}}→ 11 tahun, 0 atau 1 bulan{{age in years and months|Jan 2001|Feb 2012|range=dash}}→ 11 tahun, 0–1 bulan{{age in years and months|Jan 2001|Feb 2012|range=no}}→ 11 tahun, 1 bulan (assume 1 Jan 2001 to 1 Feb 2012){{age in years and months|12 Jan 2001|Feb 2012|range=no}}→ 11 tahun, 1 bulan (assume 12 Jan 2001 to 12 Feb 2012){{age in years and months|2001|2012|range=no}}→ 11 tahun (assume 1 Jan 2001 to 1 Jan 2012){{age in years and months|2001|23 Feb 2012|range=no}}→ 11 tahun (assume 23 Feb 2001 to 23 Feb 2012)
The sort key is based on the age in days, and fractions of a day if a time is specified.
{{age in years and months|10 Jan 2001|20 Feb 2012|sortable=debug}}→ 7003405800000000000♠11 tahun, 1 bulan{{age in years and months|10 Jan 2001|6:00 am 20 Feb 2012|sortable=debug}}→ 7003405825000000000♠11 tahun, 1 bulan{{age in years and months|10 Jan 2001|6:00 am 20 Feb 2012|sortable=debug|show=hide}}→ 7003405825000000000♠
An extra day is added for a duration.
{{age in years and months|20 Jan 2001|19 Feb 2012}}→ 11 tahun (one day short of 11 years, 1 month){{age in years and months|20 Jan 2001|19 Feb 2012|duration=on}}→ 11 tahun, 1 bulan
The least-significant time unit can be rounded.
{{age in years and months|20 Jan 2001|10 Feb 2012}}→ 11 tahun{{age in years and months|20 Jan 2001|10 Feb 2012|round=on}}→ 11 tahun, 1 bulan (round to nearest month)
Large numbers can be formatted with commas.
{{age in years and months|120|2012|format=commas|range=yes}}→ 1,891 atau 1,892 tahun{{age in years and months|120|2012|format=commas|range=dash}}→ 1,891–1,892 tahun
Spelling numbersSpelling numbers
The templates that use age_generic can display numbers in words rather than using numerals. The result can be a cardinal number (such as "five") or an ordinal number (such as "fifth"). The first letter can be in uppercase, and US spelling of numbers can be used. Examples:
{{age|1898|01|01|2018|02|01|format=cardinal}}→ 120{{age|1898|01|01|2018|02|01|format=cardinal_us}}→ 120{{age|1898|01|01|2018|02|01|format=Cardinal}}→ 120{{age|1898|01|01|2018|02|01|format=Cardinal_us}}→ 120{{age|1898|01|01|2018|02|01|format=Ordinal}}→ 120{{age|1898|01|01|2018|02|01|format=Ordinal_us}}→ 120{{age|1898|01|01|2018|02|01|format=ordinal}}→ 120{{age|1898|01|01|2018|02|01|format=ordinal_us}}→ 120{{age|1980|1990|range=yes|format=Cardinal}}→ Kesalahan ekspresi: Karakter tanda baca "{" tidak dikenal.{{age in years, months and days|April 1980|1995|format=Cardinal|range=yes}}→ 14 atau 15 tahun
See alsoSee also
- {{time interval}} • This template supports all age/duration calculations and provides more options such as abbreviating or omitting units.
Penyunting dapat melakukan uji coba pada halaman bak pasir (buat | cermin) dan kasus uji (buat) modul ini.
Subhalaman modul ini.
-- Implement various "age of" and other date-related templates. local_Date,_currentDate localfunctiongetExports(frame) -- Return objects exported from the date module or its sandbox. ifnot_Datethen localsandbox=frame:getTitle():find('sandbox',1,true)and'/sandbox'or'' localdatemod=require('Module:Date'..sandbox) _Date=datemod._Date _currentDate=datemod._current end return_Date,_currentDate end localCollection-- a table to hold items Collection={ add=function(self,item) ifitem~=nilthen self.n=self.n+1 self[self.n]=item end end, join=function(self,sep) returntable.concat(self,sep) end, remove=function(self,pos) ifself.n>0and(pos==nilor(0<posandpos<=self.n))then self.n=self.n-1 returntable.remove(self,pos) end end, sort=function(self,comp) table.sort(self,comp) end, new=function() returnsetmetatable({n=0},Collection) end } Collection.__index=Collection localfunctionstripToNil(text) -- If text is a string, return its trimmed content, or nil if empty. -- Otherwise return text (which may, for example, be nil). iftype(text)=='string'then text=text:match('(%S.-)%s*$') end returntext end localfunctionyes(parameter) -- Return true if parameter should be interpreted as "yes". -- Do not want to accept mixed upper/lowercase unless done by current templates. -- Need to accept "on" because "round=on" is wanted. return({y=true,yes=true,on=true})[parameter] end localfunctionmessage(msg,id) -- Return formatted message text for an error or warning. localcategories={ error='[[Category:Age error]]', warning='[[Category:Age error]]',-- same as error until determine whether 'Age warning' would be worthwhile } locala,b,category ifid=='warning'then a='<sup>[<i>' b='</i>]</sup>' else a='<strong class="error">Error: ' b='</strong>' end ifmw.title.getCurrentTitle():inNamespaces(0)then -- Category only in namespaces: 0=article. category=categories[idor'error'] end return a.. mw.text.nowiki(msg).. b.. (categoryor'') end localfunctionformatNumber(number) -- Return the given number formatted with commas as group separators, -- given that the number is an integer. localnumstr=tostring(number) locallength=#numstr localplaces=Collection.new() localpos=0 repeat places:add(pos) pos=pos+3 untilpos>=length places:add(length) localgroups=Collection.new() fori=places.n,2,-1do localp1=length-places[i]+1 localp2=length-places[i-1] groups:add(numstr:sub(p1,p2)) end returngroups:join(',') end localfunctionmakeSort(value,sortable) -- Return a sort key if requested. -- Assume value is a valid number which has not overflowed. ifsortable=='sortable_table'orsortable=='sortable_on'orsortable=='sortable_debug'then localsortkey ifvalue==0then sortkey='5000000000000000000' else localmag=math.floor(math.log10(math.abs(value))+1e-14) localprefix ifvalue>0then prefix=7000+mag else prefix=2999-mag value=value+10^(mag+1) end sortkey=string.format('%d',prefix)..string.format('%015.0f',math.floor(value*10^(14-mag))) end locallhs,rhs ifsortable=='sortable_table'then lhs='data-sort-value="' rhs='"|' else lhs=sortable=='sortable_debug'and '<span style="border:1px solid;display:inline;" class="sortkey">'or '<span style="display:none" class="sortkey">' rhs='♠</span>' end returnlhs..sortkey..rhs end end localtranslateParameters={ abbr={ off='abbr_off', on='abbr_on', }, disp={ age='disp_age', raw='disp_raw', }, format={ raw='format_raw', commas='format_commas', }, round={ on='on', yes='on', bulan='ym', minggu='ymw', hari='ymd', jam='ymdh', }, sep={ comma='sep_comma', [',']='sep_comma', serialcomma='sep_serialcomma', space='sep_space', }, show={ hide={id='hide'}, y={'y',id='y'}, ym={'y','m',id='ym'}, ymd={'y','m','d',id='ymd'}, ymw={'y','m','w',id='ymw'}, ymwd={'y','m','w','d',id='ymwd'}, yd={'y','d',id='yd',keepZero=true}, m={'m',id='m'}, md={'m','d',id='md'}, w={'w',id='w'}, wd={'w','d',id='wd'}, h={'H',id='h'}, hm={'H','M',id='hm'}, hms={'H','M','S',id='hms'}, d={'d',id='d'}, dh={'d','H',id='dh'}, dhm={'d','H','M',id='dhm'}, dhms={'d','H','M','S',id='dhms'}, ymdh={'y','m','d','H',id='ymdh'}, ymdhm={'y','m','d','H','M',id='ymdhm'}, ymwdh={'y','m','w','d','H',id='ymwdh'}, ymwdhm={'y','m','w','d','H','M',id='ymwdhm'}, }, sortable={ off=false, on='sortable_on', table='sortable_table', debug='sortable_debug', }, } localfunctiondateExtract(frame) -- Return part of a date after performing an optional operation. localDate=getExports(frame) localargs=frame:getParent().args localparms={} fori,vinipairs(args)do parms[i]=v end ifyes(args.fix)then table.insert(parms,'fix') end ifyes(args.partial)then table.insert(parms,'partial') end localdate=Date(unpack(parms)) ifnotdatethen returnmessage('Need valid date') end localadd=stripToNil(args.add) ifaddthen foriteminadd:gmatch('%S+')do date=date+item ifnotdatethen returnmessage('Cannot add "'..item..'"') end end end localprefix,result localsortable=translateParameters.sortable[args.sortable] ifsortablethen localvalue=(date.partialanddate.partial.firstordate).jdz prefix=makeSort(value,sortable) end localshow=stripToNil(args.show)or'dmy' ifshow~='hide'then result=date[show] ifresult==nilthen result=date:text(show) elseiftype(result)=='boolean'then result=resultand'1'or'0' else result=tostring(result) end end return(prefixor'')..(resultor'') end localfunctionmakeText(values,components,names,options) -- Return wikitext representing an age or duration. localtext=Collection.new() localcount=#values localsep=names.sepor'' fori,vinipairs(values)do -- v is a number (say 4 for 4 years), or a table ({4,5} for 4 or 5 years). localislist=type(v)=='table' if(islistorv>0)or(text.n==0andi==count)or(text.n>0andcomponents.keepZero)then localfmt,vstr ifi==1andoptions.format=='format_commas'then -- Numbers after the first should be small and not need formatting. fmt=formatNumber else fmt=tostring end ifislistthen localjoin=options.range=='dash'and'–'or' atau ' vstr=fmt(v[1])..join..fmt(v[2]) else vstr=fmt(v) end localname=names[components[i]] ifnamethen localplural=names.plural ifnotpluralor(islistandv[2]orv)==1then plural='' end text:add(vstr..sep..name..plural) else text:add(vstr) end end end localfirst,last ifoptions.join=='sep_space'then first=' ' last=' ' elseifoptions.join=='sep_comma'then first=', ' last=', ' elseifoptions.join=='sep_serialcomma'andtext.n>2then first=', ' last=', dan ' else first=', ' last=' dan ' end fori,vinipairs(text)do ifi<text.nthen text[i]=v..(i+1<text.nandfirstorlast) end end localsign='' ifoptions.isnegativethen -- Do not display negative zero. iftext.n>1or(text.n==1andtext[1]:sub(1,1)~='0')then ifoptions.format=='format_raw'then sign='-'-- plain hyphen so result can be used in a calculation else sign='−'-- Unicode U+2212 MINUS SIGN end end end return (options.prefixor'').. sign.. text:join().. (options.suffixor'') end localfunctiondateDifference(parms) -- Return a formatted date difference using the given parameters -- which have been validated. localnames={ abbr_off={ plural='', sep=' ', y='tahun', m='bulan', w='minggu', d='hari', H='jam', M='menit', S='detik', }, abbr_on={ y='thn', m='bln', w='mgg', d='hr', H='jam', M='mnt', S='dtk', }, abbr_infant={-- for {{age for infant}} plural='', sep=' ', y='thn', m='bln', w='mgg', d='hr', H='jam', M='mnt', S='dtk', }, abbr_raw={}, } localdiff=parms.diff-- must be a valid date difference localshow=parms.show-- may be nil; default is set below localabbr=parms.abbror'abbr_off' localdefaultJoin ifabbr~='abbr_off'then defaultJoin='sep_space' end ifnotshowthen show='ymd' ifparms.disp=='disp_age'then ifdiff.years<3then defaultJoin='sep_space' ifdiff.years>=1then show='ym' else show='md' end else show='y' end end end iftype(show)~='table'then show=translateParameters.show[show] end ifparms.disp=='disp_raw'then defaultJoin='sep_space' abbr='abbr_raw' elseifparms.wantScthen defaultJoin='sep_serialcomma' end localdiffOptions={ round=parms.round, duration=parms.wantDuration, range=parms.rangeandtrueornil, } localprefix ifparms.sortablethen localvalue=diff.age_days+(parms.wantDurationand1or0)-- days and fraction of a day ifdiff.isnegativethen value=-value end prefix=makeSort(value,parms.sortable) end localtextOptions={ prefix=prefix, suffix=parms.suffix,-- not currently used format=parms.format, join=parms.sepordefaultJoin, isnegative=diff.isnegative, range=parms.range, } ifshow.id=='hide'then returnprefixor'' end localvalues={diff:age(show.id,diffOptions)} ifvalues[1]then returnmakeText(values,show,names[abbr],textOptions) end ifdiff.partialthen -- Handle a more complex range such as -- {{age_yd|20 Dec 2001|2003|range=yes}} → 1 year, 12 days or 2 years, 11 days localopt={ format=textOptions.format, join=textOptions.join, isnegative=textOptions.isnegative, } return (textOptions.prefixor'').. makeText({diff.partial.mindiff:age(show.id,diffOptions)},show,names[abbr],opt).. (textOptions.range=='dash'and'–'or' atau ').. makeText({diff.partial.maxdiff:age(show.id,diffOptions)},show,names[abbr],opt).. (textOptions.suffixor'') end returnmessage('Parameter show='..show.id..' is not supported here') end localfunctiongetDates(frame,getopt) -- Parse template parameters and return one of: -- * date (a date table, if single) -- * date1, date2 (two date tables, if not single) -- * text (a string error message) -- A missing date is replaced with the current date. -- If wantMixture is true, a missing date component is replaced -- from the current date, so can get a bizarre mixture of -- specified/current y/m/d as has been done by some "age" templates. -- Some results may be placed in table getopt. localDate,currentDate=getExports(frame) getopt=getoptor{} localfix=getopt.fixand'fix'or'' localpartial=getopt.partialand'partial'or'' localargs=frame:getParent().args localfields={} localisNamed=args.yearorargs.year1orargs.year2or args.monthorargs.month1orargs.month2or args.dayorargs.day1orargs.day2 ifisNamedthen fields[1]=args.year1orargs.year fields[2]=args.month1orargs.month fields[3]=args.day1orargs.day fields[4]=args.year2 fields[5]=args.month2 fields[6]=args.day2 else fori=1,6do fields[i]=args[i] end end localimax=0 fori=1,6do fields[i]=stripToNil(fields[i]) iffields[i]then imax=i end end localnoDefault=imax==0andgetopt.noMissing localdates={} ifisNamedorimax>=3then localnrDates=getopt.singleand1or2 ifgetopt.wantMixturethen -- Cannot be partial since empty fields are set from current. localcomponents={'year','month','day'} fori=1,nrDates*3do fields[i]=fields[i]orcurrentDate[components[i>3andi-3ori]] end fori=1,nrDatesdo localindex=i==1and1or4 dates[i]=Date(fields[index],fields[index+1],fields[index+2]) end else fori=1,nrDatesdo localindex=i==1and1or4 localy,m,d=fields[index],fields[index+1],fields[index+2] if(partialandy)or(yandmandd)then dates[i]=Date(fix,partial,y,m,d) elseifnotyandnotmandnotdandnotnoDefaultthen dates[i]=Date('currentdate') end end end elseifnotnoDefaultthen getopt.textdates=true-- have parsed each date from a single text field dates[1]=Date(fix,partial,fields[1]or'currentdate') ifnotgetopt.singlethen dates[2]=Date(fix,partial,fields[2]or'currentdate') end end ifnotdates[1]then returnmessage('Need valid year, month, day') end ifgetopt.singlethen returndates[1] end ifnotdates[2]then returnmessage('Second date should be year, month, day') end returndates[1],dates[2] end localfunctionageGeneric(frame) -- Return the result required by the specified template. -- Can use sortable=x where x = on/table/off/debug in any supported template. -- Some templates default to sortable=on but can be overridden. localname=frame.args.template ifnotnamethen returnmessage('The template invoking this must have "|template=x" where x is the wanted operation') end localargs=frame:getParent().args localspecs={ age_days={-- {{age in days}} show='d', disp='disp_raw', }, age_days_nts={-- {{age in days nts}} show='d', disp='disp_raw', format='format_commas', sortable='on', }, duration_days={-- {{duration in days}} show='d', disp='disp_raw', duration=true, }, duration_days_nts={-- {{duration in days nts}} show='d', disp='disp_raw', format='format_commas', sortable='on', duration=true, }, age_full_years={-- {{age}} show='y', abbr='abbr_raw', }, age_full_years_nts={-- {{age nts}} show='y', abbr='abbr_raw', format='format_commas', sortable='on', }, age_in_years={-- {{age in years}} show='y', abbr='abbr_raw', negative='error', range='dash', }, age_in_years_nts={-- {{age in years nts}} show='y', abbr='abbr_raw', negative='error', range='dash', format='format_commas', sortable='on', }, age_infant={-- {{age for infant}} -- Do not set show because special processing is done later. abbr=yes(args.abbr)and'abbr_infant'or'abbr_off', disp='disp_age', sep='sep_space', sortable='on', }, age_m={-- {{age in months}} show='m', disp='disp_raw', }, age_w={-- {{age in weeks}} show='w', disp='disp_raw', }, age_wd={-- {{age in weeks and days}} show='wd', }, age_yd={-- {{age in years and days}} show='yd', format='format_commas', sep=args.sep~='and'and'sep_comma'ornil, }, age_yd_nts={-- {{age in years and days nts}} show='yd', format='format_commas', sep=args.sep~='and'and'sep_comma'ornil, sortable='on', }, age_ym={-- {{age in years and months}} show='ym', sep='sep_comma', }, age_ymd={-- {{age in years, months and days}} show='ymd', range=true, }, age_ymwd={-- {{age in years, months, weeks and days}} show='ymwd', wantMixture=true, }, } localspec=specs[name] ifnotspecthen returnmessage('The specified template name is not valid') end ifname=='age_days'then localsu=stripToNil(args['show unit']) ifsuthen ifsu=='abbr'orsu=='full'then spec.disp=nil spec.abbr=su=='abbr'and'abbr_on'ornil end end end localpartial localrange=stripToNil(args.range)orspec.range ifrangethen -- Suppose partial dates are used and age could be 11 or 12 years. -- "|range=" (empty value) has no effect (spec is used). -- "|range=yes" or spec.range == true sets range = true (gives "11 or 12") -- "|range=dash" sets range = 'dash' (gives "11–12"). -- "|range=no" sets range = nil (gives "12"). -- Above gives a good result with age in years, but is probably unhelpful for other cases. -- {{age in years|year1=1900|year2=1910|range=no}} → 10 -- {{age in days|year1=1900|year2=1910|range=no}} → 4016 (from 1900-01-01 to 1910-12-31) -- "|range=OTHER" sets range = nil and rejects partial dates. range=({dash='dash',no='no',[true]=true})[range]oryes(range) ifrangethen partial=true-- accept partial dates with a possible age range for the result ifrange=='no'then range=nil end end end localgetopt={ fix=yes(args.fix), partial=partial, wantMixture=spec.wantMixture, } localdate1,date2=getDates(frame,getopt) iftype(date1)=='string'then returndate1 end localformat=stripToNil(args.format) ifformatthen format='format_'..format elseifname=='age_days'andgetopt.textdatesthen format='format_commas' end localparms={ diff=date2-date1, wantDuration=spec.durationoryes(args.duration), range=range, wantSc=yes(args.sc), show=args.show=='hide'and'hide'orspec.show, abbr=spec.abbr, disp=spec.disp, format=formatorspec.format, round=yes(args.round), sep=spec.sep, sortable=translateParameters.sortable[args.sortableorspec.sortable], } if(spec.negativeorframe.args.negative)=='error'andparms.diff.isnegativethen returnmessage('The second date should not be before the first date') end returndateDifference(parms) end localfunctionbda(frame) -- Implement [[Template:Birth date and age]]. localargs=frame:getParent().args localoptions={noMissing=true,single=true} localdate=getDates(frame,options) iftype(date)=='string'then returndate-- error text end localDate=getExports(frame) localdiff=Date('currentdate')-date ifdiff.isnegativeordiff.years>150then returnmessage('Invalid birth date for calculating age') end localdisp,show='disp_raw','y' ifdiff.years<2then disp='disp_age' ifdiff.years==0anddiff.months==0then show='d' else show='m' end end localdf=stripToNil(args.df)-- day first (dmy); default is month first (mdy) -- Diubah ke %b untuk bulan pendek 3 huruf (Jan, Feb, dst) localresult=dfand '%b %-d, %-Y'or '%-d %b %-Y' result='(<span class="bday">%-Y-%m-%d</span>) </span>'..result result='<span style="display:none"> '.. date:text(result).. '<span class="noprint ForceAgeToShow"> '.. -- Diubah format usia dengan <abbr> tooltip '(<abbr title="Usia">u.</abbr> '.. dateDifference({ diff=diff, show=show, abbr='abbr_off', disp=disp, sep='sep_space', }).. ')</span>' localwarnings=tonumber(frame.args.warnings) ifwarningsandwarnings>0then localgood={ df=true, mf=true, template=true, day=true, day1=true, month=true, month1=true, year=true, year1=true, } localinvalid localimax=options.textdatesand1or3 fork,_inpairs(args)do iftype(k)=='number'then ifk>imaxthen invalid=tostring(k) break end else ifnotgood[k]then invalid=k break end end end ifinvalidthen result=result..message('invalid parameter '..invalid,'warning') end end returnresult end localfunctiondateToGsd(frame) -- Implement [[Template:Gregorian serial date]]. -- Return Gregorian serial date of the given date, or the current date. -- The returned value is negative for dates before 1 January 1 AD -- despite the fact that GSD is not defined for such dates. localdate=getDates(frame,{wantMixture=true,single=true}) iftype(date)=='string'then returndate end returntostring(date.gsd) end localfunctionjdToDate(frame) -- Return formatted date from a Julian date. -- The result includes a time if the input includes a fraction. -- The word 'Julian' is accepted for the Julian calendar. localDate=getExports(frame) localargs=frame:getParent().args localdate=Date('juliandate',args[1],args[2]) ifdatethen returndate:text() end returnmessage('Need valid Julian date number') end localfunctiondateToJd(frame) -- Return Julian date (a number) from a date which may include a time, -- or the current date ('currentdate') or current date and time ('currentdatetime'). -- The word 'Julian' is accepted for the Julian calendar. localDate=getExports(frame) localargs=frame:getParent().args localdate=Date(args[1],args[2],args[3],args[4],args[5],args[6],args[7]) ifdatethen returntostring(date.jd) end returnmessage('Need valid year/month/day or "currentdate"') end localfunctiontimeInterval(frame) -- Implement [[Template:Time interval]]. -- There are two positional arguments: date1, date2. -- The default for each is the current date and time. -- Result is date2 - date1 formatted. localDate=getExports(frame) localargs=frame:getParent().args localparms={ wantDuration=yes(args.duration), range=yes(args.range)or(args.range=='dash'and'dash'ornil), wantSc=yes(args.sc), } localfix=yes(args.fix)and'fix'or'' localdate1=Date(fix,'partial',stripToNil(args[1])or'currentdatetime') ifnotdate1then returnmessage('Invalid start date in first parameter') end localdate2=Date(fix,'partial',stripToNil(args[2])or'currentdatetime') ifnotdate2then returnmessage('Invalid end date in second parameter') end parms.diff=date2-date1 forargname,translateinpairs(translateParameters)do localparm=stripToNil(args[argname]) ifparmthen parm=translate[parm] ifparm==nilthen-- test for nil because false is a valid setting returnmessage('Parameter '..argname..'='..args[argname]..' is invalid') end parms[argname]=parm end end ifparms.roundthen localround=parms.round localshow=parms.show ifround~='on'then ifshowthen ifshow.id~=roundthen returnmessage('Parameter show='..args.show..' conflicts with round='..args.round) end else parms.show=translateParameters.show[round] end end parms.round=true end returndateDifference(parms) end return{ age_generic=ageGeneric,-- can emulate several age templates birth_date_and_age=bda,-- Templat:Birth_date_and_age gsd=dateToGsd,-- Template:Gregorian_serial_date extract=dateExtract,-- Template:Extract jd_to_date=jdToDate,-- Template:? JULIANDAY=dateToJd,-- Template:JULIANDAY time_interval=timeInterval,-- Template:Time_interval }