European public holiday leaderboard

I work in a lot of European projects.  This means that we often have weekly teleconferences across several countries which are often scuppered by a partner or partners being on holiday because of a national holiday. In the UK, all our public holidays are put on Mondays (with some Fridays) so that you don’t get the country shutting down in the middle of the week. In other countries the public holidays (e.g. saints’ days) just land on the same date every year with two results:

  1. Sometimes they land on a weekend so most people don’t actually get a holiday.
  2. When they land on a Tuesday or a Thursday lots of people take off the Monday or Friday as well to make a really long weekend and you lose almost half a week.

There is often the feeling expressed that we in the UK don’t get as many holidays as the rest of Europe, but is it true? Euroalert have published an iCalendar format file of all the public holidays for the whole of the European Union. This is very handy as you can import it into Outlook (for instance) and see when a partner is going to be on holiday. As it is in iCalendar format you can also parse it yourself easily and do some investigation:

#!/usr/bin/env python2.7

# This code is written by Stephen C Phillips.
# It is in the public domain, so you can do what you like with it
# but a link to http://scphillips.com would be nice.

from datetime import date as ddate

class Holiday:
    def __init__(self, date, country):
        d = ddate(int(date[:4]),
                 int(date[4:6]),
                 int(date[6:])
                 )
        self.date = d
        self.country = country

    def __str__(self):
        return self.country + ': ' + str(self.date)

    def _get_day(self):
        # Monday is 0, Sunday is 6
        return self.date.weekday()

    day = property(_get_day)

#http://euroalert.net/dl/docs/open-data/euroalert-Public-Holidays-EU-2012.ics
cal_file = file('c:/tmp/euroalert-Public-Holidays-EU-2012.ics')

holidays = []

ignore_weekends = 1

for line in cal_file:
    line = line[:-1]
    if line.startswith('DTSTART'):
        date = line[-8:]
    if line.startswith('SUMMARY'):
        country = line[8:]
        if '/' in country:
            country = country[:country.index('/')]
        hol = Holiday(date, country)
        if ignore_weekends and hol.day >= 5:
            pass
        else:
            holidays.append(hol)

holidays_by_country = {}
for h in holidays:
    holidays_by_country.setdefault(h.country, [])
    holidays_by_country[h.country].append(h)

countries = holidays_by_country.keys()

countries_by_holidays = {}
for c, h in holidays_by_country.items():
    num = len(h)
    countries_by_holidays.setdefault(num, [])
    countries_by_holidays[num].append(c)

print "*** LEADERBOARD ***"
for n in sorted(countries_by_holidays.keys(), reverse=True):
    print n, ':', countries_by_holidays[n]
print "*******************"

def get_days(countries):
    "Return the number of times not all partners will be on a call for each day of the week."
    holidays_by_date = {}
    for c in countries:
        for h in holidays_by_country1:
            holidays_by_date.setdefault(h.date, [])
            holidays_by_date[h.date].append(h)

    dates = holidays_by_date.keys()
    days = [0,0,0,0,0,0,0]
    for date in dates:
        day = date.weekday()
        #days[day] += len(holidays_by_date[date])  # this would tell you how many partners would be missing in total
        days[day] += 1  # this is how many times not all partners are present
    return days

project_countries = ['Austria', 'Belgium', 'France', 'Greece', 'Spain', 'Sweden', 'Wales and England']
days = get_days(project_countries)
print
print project_countries
print days

That script expects you’ve downloaded the iCalendar file yourself. It parses the file and outputs some info:

*** LEADERBOARD ***
17 : ['Belgium']
14 : ['Hungary']
12 : ['Slovenia']
11 : ['Northern Ireland', 'Austria', 'Cyprus']
10 : ['Malta', 'Slovakia', 'Ireland', 'Scotland']
9 : ['Italy', 'Czech Republic', 'Lithuania', 'Wales and England', 'Poland', 'Greece']
8 : ['France', 'Germany', 'Denmark', 'Spain', 'Finland', 'Sweden', 'Latvia', 'Luxembourg', 'Bulgaria', 'Portugal']
7 : ['Romania', 'Estonia']
6 : ['Netherlands']
*******************

['Austria', 'Belgium', 'France', 'Greece', 'Spain', 'Sweden', 'Wales and England']
[11, 4, 3, 6, 9, 0, 0]

So this is telling us that in 2012, Belgium had 17 days off (and this is weekdays off as the script has been set to ignore the weekends) whereas Wales & England had 9 (Scotland 10) and the poor Dutch only got 6. It also tells us that for the particular set of partners listed, Monday is a terrible day to hold a weekly teleconference (inevitable given the UK being on the list) and Wednesday is good with only 3 days when all partners wouldn’t be there.

Running the script and not ignoring the weekends gives this leaderboard:

*** LEADERBOARD ***
24 : ['Belgium']
17 : ['Hungary']
15 : ['Lithuania', 'Latvia', 'Cyprus']
14 : ['Malta', 'Slovakia', 'Bulgaria']
13 : ['Poland', 'Sweden', 'Portugal', 'Austria']
12 : ['Czech Republic', 'Slovenia', 'Finland', 'Estonia', 'Greece']
11 : ['France', 'Denmark', 'Northern Ireland', 'Romania']
10 : ['Italy', 'Ireland', 'Scotland', 'Luxembourg']
9 : ['Wales and England', 'Germany', 'Spain', 'Netherlands']
*******************

So here, Wales & England trail in last place with 9 days off and Belgium is still unassailable at the top with 24 public holidays. However, as we’ve seen, in other countries many of these “holidays” fall at the weekends so it’s not (quite) as bad as all that. The UK also has a high minimum statutory holiday allowance of 28 days paid annual leave per year. Your employer can choose whether to count the public holidays as part of this allowance though.

If someone can point me at the data for 2013 then that would be great!