Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Historic & one-off updates for South Africa #173

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG
@@ -1,6 +1,12 @@
CHANGELOG
=========

1.1.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer:

master (unreleased)
-------------------

but that's fine ; I'll fix it beforehand.

------------------

- Historical and one-off holidays for South Africa. thx @gregn610


1.0.0 (2016-12-12)
------------------

Expand Down
78 changes: 69 additions & 9 deletions workalendar/africa.py
Expand Up @@ -3,7 +3,7 @@
unicode_literals)
from datetime import timedelta, date
from workalendar.core import WesternCalendar
from workalendar.core import SUN
from workalendar.core import SUN, MON
from workalendar.core import IslamicMixin, ChristianMixin


Expand Down Expand Up @@ -97,30 +97,90 @@ class SaoTomeAndPrincipe(WesternCalendar, ChristianMixin):
class SouthAfrica(WesternCalendar, ChristianMixin):
"South Africa"
include_good_friday = True
include_easter_monday = True
include_christmas = True
include_boxing_day = True

FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
(3, 21, 'Human Rights Day'),
(4, 27, "Freedom Day"),
(5, 1, "Workers Day"),
(6, 16, "Youth Day"),
(8, 9, "National Women Day"),
(9, 24, "Heritage Day"),
(12, 16, "Day of reconcilation"),
(12, 26, "Day of good will"),
)

def get_family_day(self, year):
return (self.get_good_friday(year), "Family Day")

def get_fixed_holidays(self, year):
days = super(SouthAfrica, self).get_fixed_holidays(year)
if year < 1952:
days.append((date(year, 5, 24), "Empire Day"))
if year >= 1952 and year <= 1974:
days.append((date(year, 4, 6), "Van Riebeeck's Day"))
if year >= 1952 and year <= 1979:
days.append((self.get_nth_weekday_in_month(year, 9, MON, 1),
"Settlers' Day"))
if year >= 1952 and year <= 1993:
days.append((date(year, 10, 10), "Kruger Day"))
if year <= 1960:
days.append((date(year, 5, 31), "Union Day"))
if year > 1960 and year <= 1993:
days.append((date(year, 5, 31), "Republic Day"))
if year > 1960 and year <= 1974:
days.append((date(year, 7, 10), "Family Day"))
if year >= 1980 and year <= 1994:
days.append((date(year, 4, 6), "Founder's Day"))
if year >= 1990:
days.append((date(year, 3, 21), 'Human Rights Day'))
if year <= 1993:
days.append((self.get_ascension_thursday(year), "Ascension Day"))
if year >= 1994:
days.append((date(year, 4, 27), "Freedom Day"))
days.append((date(year, 12, 26), "Day of good will"))
if year >= 1995:
days.append((date(year, 6, 16), "Youth Day"))
days.append((date(year, 8, 9), "National Women Day"))
days.append((date(year, 9, 24), "Heritage Day"))

return days

def get_variable_days(self, year):
days = super(SouthAfrica, self).get_variable_days(year)
days.append(self.get_family_day(year))
days += self.get_fixed_holidays(year)
# compute shifting days
for month, day, label in self.FIXED_HOLIDAYS:
holiday = date(year, month, day)
for holiday, label in days:
if holiday.weekday() == SUN:
days.append((
holiday + timedelta(days=1),
"%s substitute" % label
))

# Other one-offs. Don't shift these
if year == 1999:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's an impressive list! wow! amazin work!

days.append((date(year, 6, 2), "National Elections"))
days.append((date(year, 12, 31), "Y2K"))
if year == 2000:
# 2 January 2000 public holidays to accommodate the Y2K changeover,
# 3 January 2000 because the previous holiday was a Sunday
days.append((date(year, 1, 2), "Y2K"))
days.append((date(year, 1, 3), "Y2K"))
if year == 2001:
days.append((date(year, 1, 2), "Y2K"))
if year == 2004:
days.append((date(year, 4, 14), "National Elections"))
if year == 2006:
days.append((date(year, 3, 1), "Local Elections"))
if year == 2008:
# 2 May 2008 was declared a public holiday when Human Rights Day
# and Good Friday coincided on 21 March 2008
days.append((date(year, 5, 2), "Special Human Rights"))
if year == 2009:
days.append((date(year, 4, 22), "National Elections"))
if year == 2011:
days.append((date(year, 5, 18), "Local Elections"))
days.append((date(year, 12, 27), "Special Day of Goodwill"))
if year == 2014:
days.append((date(year, 5, 7), "National Elections"))
if year == 2016:
days.append((date(year, 8, 3), "Local Elections"))

return days
86 changes: 85 additions & 1 deletion workalendar/tests/test_africa.py
Expand Up @@ -4,6 +4,7 @@
from workalendar.africa import Benin, Algeria
from workalendar.africa import SouthAfrica, IvoryCoast
from workalendar.africa import SaoTomeAndPrincipe, Madagascar
from workalendar.core import MON


class AlgeriaTest(GenericCalendarTest):
Expand Down Expand Up @@ -51,8 +52,8 @@ def test_year_2013(self):
holidays = self.cal.holidays_set(2013)
self.assertIn(date(2013, 1, 1), holidays) # new year
self.assertIn(date(2013, 3, 21), holidays) # human rights day
# good friday, becoming family day
self.assertIn(date(2013, 3, 29), holidays)
self.assertIn(date(2013, 4, 1), holidays) # Easter monday / Family day
self.assertIn(date(2013, 4, 27), holidays) # freedom day
self.assertIn(date(2013, 5, 1), holidays) # labour day
self.assertIn(date(2013, 6, 16), holidays) # youth day
Expand All @@ -69,6 +70,89 @@ def test_year_2014(self):
self.assertIn(date(2014, 4, 27), holidays) # freedom day
self.assertIn(date(2014, 4, 28), holidays) # freedom day sub

# def test_pre_1994(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, you might not necessarily leave these comments here.

# pass
#
# def test_pre_1995(self):
# pass

def test_special_1999(self):
# National and provincial government elections – 2 June 1999[8]
holidays = self.cal.holidays_set(1999)
self.assertIn(date(1999, 6, 2), holidays)

def test_special_2000(self):
holidays = self.cal.holidays_set(2000)
self.assertIn(date(2000, 1, 2), holidays)
self.assertIn(date(2000, 1, 3), holidays)

def test_special_2004(self):
# National and provincial government elections – 14 April 2004[9]
holidays = self.cal.holidays_set(2004)
self.assertIn(date(2004, 4, 14), holidays)

def test_special_2006(self):
# Local government elections – 1 March 2006[10]
holidays = self.cal.holidays_set(2006)
self.assertIn(date(2006, 3, 1), holidays)

def test_special_2008(self):
# 2 May 2008 was declared a public holiday when Human Rights Day
# and Good Friday coincided on 21 March 2008.
holidays = self.cal.holidays_set(2008)
self.assertIn(date(2008, 5, 2), holidays)

def test_special_2009(self):
# National and provincial government elections – 22 April 2009[11]
holidays = self.cal.holidays_set(2009)
self.assertIn(date(2009, 4, 22), holidays)

def test_special_2011(self):
# Local government elections – 18 May 2011[12]
holidays = self.cal.holidays_set(2011)
self.assertIn(date(2011, 5, 18), holidays)
# 27 December 2011 was declared a holiday by president Motlanthe
self.assertIn(date(2011, 12, 27), holidays)

def test_special_2014(self):
# National and provincial government elections – 7 May 2014[13]
holidays = self.cal.holidays_set(2014)
self.assertIn(date(2014, 5, 7), holidays)

def test_special_2016(self):
# Local government elections – 3 August 2016[14]
holidays = self.cal.holidays_set(2016)
self.assertIn(date(2016, 8, 3), holidays)

def test_historical_1973(self):
# Ascension Day 1910–1993
holidays = self.cal.holidays_set(1973)
self.assertIn(self.cal.get_ascension_thursday(1973), holidays)

def test_historical_1974(self):
holidays = self.cal.holidays_set(1974)
# 6 April Van Riebeeck's Day / Founder's Day
self.assertIn(date(1974, 4, 6), holidays)
# 31 May Union Day / Republic Day
self.assertIn(date(1974, 5, 31), holidays)
# 10 July Family Day 1961–1974
self.assertIn(date(1974, 7, 10), holidays)
# 1st Monday in September Settlers' Day 1952–1979
self.assertIn(self.cal.get_nth_weekday_in_month(1974, 9, MON, 1),
holidays)
# 10 October Kruger Day 1952–1993
self.assertIn(date(1974, 10, 10), holidays)

def test_historical_empire(self):
holidays = self.cal.holidays_set(1951)
# 24 May Victoria Day / Empire Day 1910–1951
self.assertIn(date(1951, 5, 24), holidays)

def test_queens_birthday(self):
# 2nd Monday in July Queen's Birthday 1952–1960
holidays = self.cal.holidays_set(1960)
self.assertIn(date(1960, 5, 2), holidays)


class Madagascar(GenericCalendarTest):
cal_class = Madagascar
Expand Down