The standard way to do this in asterisk has been doing a series of GotoIfTime statements or time-based include statements. Either way can be tedious and requires someone with access to edit asterisk config files.
With calendaring, the adminstrator only needs to set up a calendar that contains the various holidays or even recurring events specifying the office hours. A custom greeting filename could even be contained in the description field for playback. For example:
[incoming] exten => 5555551212,1,Answer exten => 5555551212,n,GotoIf(${CALENDAR_BUSY(officehours)}?closed:attendant,s,1) exten => 5555551212,n(closed),Set(id=${CALENDAR_QUERY(office,${EPOCH},${EPOCH})}) exten => 5555551212,n,Set(soundfile=${CALENDAR_QUERY_RESULT(${id},description)}) exten => 5555551212,n,Playback($[${ISNULL(soundfile)} ? generic-closed :: ${soundfile}]) exten => 5555551212,n,Hangup