views:

340

answers:

3

I'm looking for a way to figure out whether a given date is a "holiday," given some holiday calendar.

Specifically, you might say is_holiday (datetime.date, "USA") which would answer whether the given date is a holiday for the calendar named "USA."

I recognize that there's no trivial way of doing this for all holidays for all years. For example, while Christmas is always the 25th of December, for federal government purposes, sometimes we celebrate (i.e., it's not a business day) on the 24th of December, and sometimes on the 26th. Similary, Jewish holidays (for example) migrate yearly (relative to the Gregorian Calendar).

I'm not looking for calculations for each holiday. I'm wondering more if there's some accepted, standard file format that lists holidays by year, and if so, if there's any modules - in Python, specifically, but I'm flexible - that understand how to read said format. Similarly, the file format would define weekends - which are normally Saturday and Sunday, but in certain regions it may be Friday and Saturday, etc.

+3  A: 

Mozilla has a set of user-contributed holiday files in .ics format. That may get you started. Unfortunately they go out to different date ranges. iCalShare also has holiday calendars in .ics format.

Note also that some holidays are state or region-related, rather than country-related. I've found in the past that a hierarchical approach works. e.g. check for a city holiday calendar, then a state calendar, then a country calender.

There's a Python module for reading .ics files here. I can't vouch for its quality, unfortunately.

Brian Agnew
Agreed about the state/region-related... "USA" in my trivial example wasn't the country-name, it was just the name of the "calendar." Could have just as easily been `is_holiday (datetime.date, "Hello World")`
FreeMemory
I figured as much. What I've had to do in the past is implement a 'fall-back' strategy, and consequently my calendars have a concept of a hierarchy built into them. e.g. my NYC calendar knows that its 'parent' is the USA calendar etc.
Brian Agnew
A: 

The classic holiday.py module (part of an old dateutil package -- old enough to rely on module time rather than the relatively recent datetime!) does a good job of calendric calculations (including Jewish <-> Gregorian calendar translations) but does not deal with persistence (reading or writing).

As @Brian's response suggests, ics is the dominant format for "calendars" in a file (and there are holiday files, among others, in such format). To read and write ics file in Python you can for example use the iCalendar package, which does precisely that task, or vobject, which is a much broader package supporting the range of vCard and vCalendar formats (including iCalendar).

Alex Martelli
A: 

Read Calendrical Calculations: http://emr.cs.uiuc.edu/home/reingold/calendar-book/index.shtml

The various rules for US holidays are provided in details, with algorithms.

The "Celebrate" business (moving the Christmas Holiday to the 24th because the 25th falls on a Saturday) is a simple matter of checking the US Federal Holidays list.

http://www.opm.gov/Operating_Status_Schedules/fedhol/2009.asp

Individual states vary, of course, as do businesses. But that's a start.

S.Lott
I'm __not__ interested in calculating the holidays, however. Different regions, different religions and different rules make that a very difficult task. I'd be happy with storing multiple different files, each to represent a different "calendar." I was looking more for some file specification that would work without inventing my own. .ics is a start, but seems to be __too much__, as it's also used for "events," etc.
FreeMemory
@FreeMemory: "I was looking more for some file specification". Good. Update your question to actually say that very, very clearly.
S.Lott
@S. Lott: Perhaps read the last paragraph? "I'm not looking for calculations for each holiday. I'm wondering more if there's some accepted, __standard file format__ that lists holidays by year" (emphasis added).
FreeMemory
@FreeMemory: Please update your question to actually say that very, very clearly. Your question says a lot of things. Perhaps too many things. Here's the point. If someone (i.e., me) didn't get the question then perhaps it's possible that it could stand a little clarification. I'm a small sample size, but there's a possibility that it isn't *just* me.
S.Lott
I thought there was no ambiguity there at all. I am (obviously) a small sample :-)
Brian Agnew