Skip to content

Instantly share code, notes, and snippets.

@deeplook
Created May 12, 2018 21:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save deeplook/64ad3d00262acfcb2da2f943d8b21571 to your computer and use it in GitHub Desktop.
Save deeplook/64ad3d00262acfcb2da2f943d8b21571 to your computer and use it in GitHub Desktop.
List bridge days for one year and country
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Bridge Days\n",
"\n",
"Bridge days are normal working days that happen to be between two non-working days, be they holidays or weekend days (Sat/Sun). So, they should normally fall on Mondays or Fridays, unless there are, e.g. two holidays during a week, like on Monday and Wednesday (very unlikely).\n",
"\n",
"This notebook contains some very simple code to calculate the list of bridge days for some given year and country as a simple use case for the ``holidays`` pacakge, see https://pypi.org/project/holidays/."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Experiment with the `holidays` package"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from datetime import date\n",
"import holidays"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"swiss_holidays = holidays.Switzerland()"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"date(2018, 5, 9) in swiss_holidays"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"date(2018, 5, 10) in swiss_holidays"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Auffahrt'"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"swiss_holidays.get(date(2018, 5, 10))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{datetime.date(2018, 1, 1): 'Neujahr',\n",
" datetime.date(2018, 3, 30): 'Karfreitag',\n",
" datetime.date(2018, 4, 2): 'Ostermontag',\n",
" datetime.date(2018, 5, 1): 'Maifeiertag',\n",
" datetime.date(2018, 5, 10): 'Christi Himmelfahrt',\n",
" datetime.date(2018, 5, 21): 'Pfingstmontag',\n",
" datetime.date(2018, 10, 3): 'Tag der Deutschen Einheit',\n",
" datetime.date(2018, 12, 25): 'Erster Weihnachtstag',\n",
" datetime.date(2018, 12, 26): 'Zweiter Weihnachtstag'}"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"holidays.Germany(prov=\"BE\", years=2018)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{datetime.date(2018, 1, 1): 'Neujahr',\n",
" datetime.date(2018, 1, 6): 'Heilige Drei Könige',\n",
" datetime.date(2018, 3, 30): 'Karfreitag',\n",
" datetime.date(2018, 4, 2): 'Ostermontag',\n",
" datetime.date(2018, 5, 1): 'Maifeiertag',\n",
" datetime.date(2018, 5, 10): 'Christi Himmelfahrt',\n",
" datetime.date(2018, 5, 21): 'Pfingstmontag',\n",
" datetime.date(2018, 5, 31): 'Fronleichnam',\n",
" datetime.date(2018, 8, 15): 'Mariä Himmelfahrt',\n",
" datetime.date(2018, 10, 3): 'Tag der Deutschen Einheit',\n",
" datetime.date(2018, 11, 1): 'Allerheiligen',\n",
" datetime.date(2018, 12, 25): 'Erster Weihnachtstag',\n",
" datetime.date(2018, 12, 26): 'Zweiter Weihnachtstag'}"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"holidays.Germany(prov=\"BY\", years=2018)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"{datetime.date(2018, 1, 1): 'Neujahrestag',\n",
" datetime.date(2018, 4, 1): 'Ostern',\n",
" datetime.date(2018, 3, 30): 'Karfreitag',\n",
" datetime.date(2018, 4, 2): 'Ostermontag',\n",
" datetime.date(2018, 5, 1): 'Tag der Arbeit',\n",
" datetime.date(2018, 5, 10): 'Auffahrt',\n",
" datetime.date(2018, 5, 20): 'Pfingsten',\n",
" datetime.date(2018, 5, 21): 'Pfingstmontag',\n",
" datetime.date(2018, 8, 1): 'Nationalfeiertag',\n",
" datetime.date(2018, 12, 25): 'Weihnachten',\n",
" datetime.date(2018, 12, 26): 'Stephanstag'}"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"holidays.Switzerland(prov=\"BS\", years=2018)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Get all bridge days for one year"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"from datetime import datetime, timedelta\n",
"from calendar import day_name"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"def is_working_day(holi, dt):\n",
" \"\"\"Is this a working day (not a holiday or Sat/Sun)?\"\"\"\n",
" \n",
" return not (dt in holi or dt.weekday() in (5, 6))"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"def bridge_days_for_holiday(holi, dt):\n",
" \"\"\"Get working days before/after one given date (2 day window).\"\"\"\n",
" \n",
" dtm2, dtm1, dtp1, dtp2 = \\\n",
" [dt + timedelta(days=days) for days in [-2, -1, 1, 2]]\n",
" wd = is_working_day\n",
" if wd(holi, dtm1) and not wd(holi, dtm2):\n",
" yield dtm1\n",
" if wd(holi, dtp1) and not wd(holi, dtp2):\n",
" yield dtp1"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"def show_bridge_days(holi):\n",
" \"\"\"List bridge days for an entire year.\"\"\"\n",
" \n",
" for dt, name in sorted(holi.items()):\n",
" weekday = day_name[dt.weekday()]\n",
" for bridge_day in bridge_days_for_holiday(holi, dt):\n",
" print('Holiday date: {} ({}) - {} -- bridge day: {}'.format(dt, weekday, name, bridge_day))"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"berlin_holidays_2018 = holidays.Germany(prov=\"BE\", years=2018)\n",
"bavaria_holidays_2018 = holidays.Germany(prov=\"BY\", years=2018)\n",
"basel_holidays_2018 = holidays.Switzerland(prov=\"BS\", years=2018)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Holiday date: 2018-05-01 (Tuesday) - Maifeiertag -- bridge day: 2018-04-30\n",
"Holiday date: 2018-05-10 (Thursday) - Christi Himmelfahrt -- bridge day: 2018-05-11\n",
"Holiday date: 2018-12-25 (Tuesday) - Erster Weihnachtstag -- bridge day: 2018-12-24\n"
]
}
],
"source": [
"show_bridge_days(berlin_holidays_2018)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Holiday date: 2018-05-01 (Tuesday) - Maifeiertag -- bridge day: 2018-04-30\n",
"Holiday date: 2018-05-10 (Thursday) - Christi Himmelfahrt -- bridge day: 2018-05-11\n",
"Holiday date: 2018-05-31 (Thursday) - Fronleichnam -- bridge day: 2018-06-01\n",
"Holiday date: 2018-11-01 (Thursday) - Allerheiligen -- bridge day: 2018-11-02\n",
"Holiday date: 2018-12-25 (Tuesday) - Erster Weihnachtstag -- bridge day: 2018-12-24\n"
]
}
],
"source": [
"show_bridge_days(bavaria_holidays_2018)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Holiday date: 2018-05-01 (Tuesday) - Tag der Arbeit -- bridge day: 2018-04-30\n",
"Holiday date: 2018-05-10 (Thursday) - Auffahrt -- bridge day: 2018-05-11\n",
"Holiday date: 2018-12-25 (Tuesday) - Weihnachten -- bridge day: 2018-12-24\n"
]
}
],
"source": [
"show_bridge_days(basel_holidays_2018)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Challenge: Draw a world map of #holidays and #bridge days / year\n",
"\n",
"More to come… But notice, that the ``holidays`` package does not provide holidays for all countries!"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment