Asterisk cmd GotoIfTime
Created by: oej,Last modification on Wed 09 of Jul, 2008 [14:45 UTC] by erikw_sizeit.se
Synopsis:
Conditional goto on current timeDescription:
GotoIfTime(<time range>|<days of week>|<days of month>|<months>?[[context|]extension|]pri)If the current time matches the specified time, then branch to the specified extension. Each of the elements may be specified either as '*' (for always) or as a range. If the current time does not match the specified time, next priority is executed.
How to specify time
The include syntax is defined in the sample extensions.conf like this:<time range>|<days of week>|<days of month>|<months>
where:
<time range>= <hour>':'<minute>'-'<hour>':'<minute>
| "*"
<days of week> = <dayname>
| <dayname>'-'<dayname>
| "*"
<dayname> = "sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "sat"
<days of month> = <daynum>
| <daynum>'-'<daynum>
| "*"
<daynum> = a number, 1 to 31, inclusive
<hour> = a number, 0 to 23, inclusive
<minute> = a number, 0 to 59, inclusive
<months> = <monthname>
| <monthname>'-'<monthname>
| "*"
<monthname> = "jan" | "feb" | "mar" | "apr" | "may" | "jun" | "jul" | "aug" | "sep" | "oct" | "nov" | "dec"
daynames and monthnames are not case-sensitive.
If you replace an option with *, it is ignored when matching. For instance:
exten => 3000,1,GotoIfTime(9:00-17:00|mon-fri|*|*?open,s,1)
would transfer to context "open", extension s, priority 1 if it's between 9:00 and 17:00, Monday through Friday, not checking the day of month or month.
Another example:
exten => s,6,GotoIfTime(*|*|26-30|May?attendant,s,30)
would transfer to context "attendant", extension s, priority 30 at any time from May 26th though May 30th. (In this example, an office is closed for Memorial Day.)
Holidays
If the comment about holidays are true, then here's a list suitable in The United States:
Independence Day: *|*|4|jul
Christmas: *|*|25|dec
NewYear: *|*|1|jan
MartinLutherKing: *|mon|15-21|jan
Valentines: *|*|14|feb
StPatDay *|*|17|mar
Halloween *|*|31|oct
Thanksgiving *|thu|22-28|nov
MemorialDay *|mon|25-31|may
LaborDay *|mon|1-7|sep
Pres/WashBday *|mon|15-21|feb
MothersDay *|sun|8-14|may
FathersDay *|sun|15-21|jun
Easter: Good Luck! Paschal moons, etc).
2007 *|*|8|apr
2008 *|*|23|mar
2009 *|*|12|apr
2010 *|*|4|apr
2011 *|*|24|apr
2012 *|*|8|apr
2013 *|*|31|mar
2014 *|*|20|apr
2015 *|*|5|apr
2016 *|*|27|mar
2017 *|*|16|apr
2018 *|*|1|apr
2019 *|*|21|apr
2020 *|*|12|apr
2021 *|*|4|apr
2022 *|*|17|apr
2023 *|*|9|apr
2024 *|*|31|mar
2025 *|*|20|apr
2026 *|*|5|apr
2027 *|*|28|mar
2028 *|*|16|apr
2029 *|*|1|apr
2030 *|*|21|apr
2031 *|*|13|apr
2032 *|*|28|mar
2033 *|*|17|apr
2034 *|*|9|apr
2035 *|*|25|mar
2036 *|*|13|apr
2037 *|*|5|apr
2038 *|*|25|apr
2039 *|*|10|apr
Here is the calculation of Easter dates:
http://www.oremus.org/liturgy/etc/ktf/app/easter.html
No years - How do I do this without reprogramming every year?
Quite simply, because GotoIfTime doesn't care what year it is, using it for non-static dates (for example, UK bank holidays in my case) means that the system must be updated every year. If the person who knows that this must be done forgets (or is no longer associated with the phone system) then things can go horribly wrong.So.... For UK bank holidays, run the following script (which contains all UK bank holidays up to the end of 2009):
- !/bin/sh
asterisk -rx 'database put bankholiday 20060828 1'
asterisk -rx 'database put bankholiday 20061225 1'
asterisk -rx 'database put bankholiday 20061226 1'
asterisk -rx 'database put bankholiday 20070101 1'
asterisk -rx 'database put bankholiday 20070406 1'
asterisk -rx 'database put bankholiday 20070409 1'
asterisk -rx 'database put bankholiday 20070507 1'
asterisk -rx 'database put bankholiday 20070528 1'
asterisk -rx 'database put bankholiday 20070827 1'
asterisk -rx 'database put bankholiday 20071225 1'
asterisk -rx 'database put bankholiday 20071226 1'
asterisk -rx 'database put bankholiday 20080101 1'
asterisk -rx 'database put bankholiday 20080321 1'
asterisk -rx 'database put bankholiday 20080324 1'
asterisk -rx 'database put bankholiday 20080505 1'
asterisk -rx 'database put bankholiday 20080526 1'
asterisk -rx 'database put bankholiday 20080825 1'
asterisk -rx 'database put bankholiday 20081225 1'
asterisk -rx 'database put bankholiday 20081226 1'
asterisk -rx 'database put bankholiday 20090101 1'
asterisk -rx 'database put bankholiday 20090410 1'
asterisk -rx 'database put bankholiday 20090413 1'
asterisk -rx 'database put bankholiday 20090504 1'
asterisk -rx 'database put bankholiday 20090525 1'
asterisk -rx 'database put bankholiday 20090831 1'
asterisk -rx 'database put bankholiday 20091225 1'
asterisk -rx 'database put bankholiday 20091228 1'
exit
and then use the following in your dialplan:
exten => s,n,Set(BANKHOLIDAY=${DB_EXISTS(bankholiday/${TIMESTAMP:0:8})})
${BANKHOLIDAY} will now be either '0' or '1' and this can be used to do your GotoIf's on!
See also
- Asterisk func IFTIME: IFTIME function
- Asterisk config extensions.conf
- Asterisk cmd goto
- Asterisk - documentation of application commands
- Asterisk tips openhours
Asterisk | Applications | Functions | Variables | Expressions | Asterisk FAQ


Comments
333Calculating Easter and Related Holidays
[macro-calceaster] ; ARG1 = year (optional)
exten => s,1,Set(year=${ARG1})
exten => s,n,GotoIf($[0${year}>0]?skip)
exten => s,n,Set(year=${STRFTIME(||%G)})
exten => s,n(skip),Set(G=${MATH(${year}%19|i)})
exten => s,n,Set(C=${MATH(${year}/100|i)})
exten => s,n,Set(H=${MATH(${MATH(${MATH(${MATH(${MATH(${C}-${MATH(${C}/4|i)}|i)}-${MATH(${MATH(${MATH(${C}*8|i)}+13|i)}/25|i)}|i)}+${MATH(${G}*19|i)}|i)}+15|i)}%30|i)})
exten => s,n,Set(I=${MATH(${H}-${MATH(${MATH(${MATH(${H}/28|i)}*${MATH(1-${MATH(29/${MATH(${H}+1|i)}|i)}|i)}|i)}*${MATH(${MATH(21-${G}|i)}/11|i)}|i)}|i)})
exten => s,n,Set(J=${MATH(${MATH(${MATH(${MATH(${MATH(${MATH(${MATH(${year}/4|i)}+${year}|i)}+${I}|i)}+2|i)}-${C}|i)}+${MATH(${C}/4|i)}|i)}%7|i)})
exten => s,n,Set(L=${MATH(${I}-${J}|i)})
exten => s,n,Set(M=${MATH(${MATH(${MATH(${L}+40|i)}/44|i)}+3|i)})
exten => s,n,Set(easter=${STRPTIME(${year}${M}${MATH(${MATH(28-${MATH(${MATH(${M}/4|i)}*31|i)}|i)}+${L}|i)}|GMT|%Y%m%d)})
exten => s,n,Set(DB(holidays/${STRFTIME(${MATH(${easter}-${MATH(2*86400)})}|GMT|%G%m%d)})=Good Friday)
exten => s,n,Set(DB(holidays/${STRFTIME(${MATH(${easter}+${MATH(1*86400)})}|GMT|%G%m%d)})=Easter Monday)
exten => s,n,Set(DB(holidays/${STRFTIME(${MATH(${easter}+${MATH(39*86400)})}|GMT|%G%m%d)})=Ascension Day)
exten => s,n,Set(DB(holidays/${STRFTIME(${MATH(${easter}+${MATH(50*86400)})}|GMT|%G%m%d)})=Pentecost Monday)
333if-holiday macro
I'm using the following macro to check whether today is a holiday or not:
--
[macro-if-holiday]
exten => s,1,NoOp(Checking if today is a holiday)
exten => s,n,Set(YEAR=${STRFTIME(${EPOCH},,%Y)})
exten => s,n,Set(MONTHDAY=${STRFTIME(${EPOCH},,%m%d)})
exten => s,n,NoOp(Today's date is ${YEAR}${MONTHDAY})
exten => s,n,GotoIf(${DB_EXISTS(HOLIDAYS/${MONTHDAY})}?s-FIXED,1)
exten => s,n,GotoIf(${DB_EXISTS(HOLIDAYS/${YEAR}${MONTHDAY})}?s-MOVING,1)
exten => s,n,NoOp(* Today is NOT a holiday)
exten => s,n,Goto(${ARG4},${ARG5},${ARG6})
exten => s-FIXED,1,NoOp(* Today is a FIXED holiday: ${MONTHDAY} ${DB(HOLIDAYS/${MONTHDAY})})
exten => s-FIXED,n,Goto(${ARG1},${ARG2},${ARG3})
exten => s-MOVING,1,NoOp(* Today is a MOVING holiday: ${YEAR}${MONTHDAY} ${DB(HOLIDAYS/${YEAR}${MONTHDAY})})
exten => s-MOVING,n,Goto(${ARG1},${ARG2},${ARG3})
--
More info on my blog here: http://www.bisente.com/blog/2007/04/30/asterisk-holidays/?lan=english
It's astdb-based, so it is completely dynamic and doesn't have any dependency (cron, shell scripts, etc.) outside Asterisk itself.
333Specifying a range does not work for months?
If I set up something like:
GotoIfTime("Zap/1-1", "08:00-11:00|sat|*|oct-dec?incoming-emerg|s|1")
this goto statemente is executed only on October and December, and NOT on November.
333Easter calculation
http://www.openofficetips.com/blog/archives/2005/03/easter_formula.html
Undrhil
333
exten => s,2,GotoIfTime(*|wed|*|*?open,s,1)
exten => s,3,GotoIfTime(*|fri|*|*?open,s,1)
exten => s,4,Goto(closed,s,1)
333Several Days Not In Range
333Several Days Not In Range
333Holiday timing...
GotoIfTime(*|mon|1-7|September?holiday,s,1)
It would only match if it's the first Monday of September, I would think. Or would that just confuse the parser?
333Re: noticeable delay on this cmd
The problem was related to something totally unrelated to *
333noticeable delay on this cmd