Repository: peopledoc/workalendar
Pull request #647 (2021-04-30 08:44:46)

Update Barbados calendar with public holiday 2021
refs #

<!-- if your contribution is a fix -->

- [x] Tests with a significant number of years to be tested for your calendar.
- [x] Changelog amended with a mention describing your changes. **Note** *Please do NOT change the version number here. It's the project maintainers' duty.*

Two new non computable holiday have been added plus two fixes for boxing day that behaves differently in barbados and the collision of Emancipation Day and Independence Day.

Here is the official source for the fixes: https://labour.gov.bb/library/library-publications/holidays/
And the official source for the annoncement of the two public holiday: https://gisbarbados.gov.bb/download/official-gazette-january-2-2021-part-a-no-1-package/ (page4) 


brunobord: oh cool! it looks like we need a hotfix release, even if it arrives a bit too late for the january extra-holidays :(
thanks for the patch!
brunobord: In any case, if you need some help, do not hesitate to ping me :o)

Patch:
diff --git a/Changelog.md b/Changelog.md
index 34f14c3..e12e0e9 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,7 +2,7 @@
 
 ## master (unreleased)
 
-Nothing here yet.
+- Fix Barbados calendar to add 2 non computable public holiday and fix boxing day computation.
 
 ## v15.2.0 (2021-04-23)
 
diff --git a/workalendar/america/barbados.py b/workalendar/america/barbados.py
index 1464d36..03a11fd 100644
--- a/workalendar/america/barbados.py
+++ b/workalendar/america/barbados.py
@@ -1,7 +1,7 @@
-from datetime import timedelta
 from copy import copy
+from datetime import date, timedelta
 
-from ..core import WesternCalendar, SUN, MON
+from ..core import MON, SUN, WesternCalendar
 from ..registry_tools import iso_register
 
 
@@ -15,14 +15,20 @@ class Barbados(WesternCalendar):
     include_easter_sunday = True
     include_easter_monday = True
     include_whit_monday = True
-    include_boxing_day = True
+    non_computable_holiday_dict = {
+        2016: [(date(2016, 12, 27), "Public Holiday")],
+        2021: [
+            (date(2021, 1, 4), "Public Holiday"),
+            (date(2021, 1, 5), "Public Holiday"),
+            ],
+    }
 
     # All holiday are shifted if on a Sunday
     FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
         (1, 21, "Errol Barrow Day"),
         (4, 28, "National Heroes Day"),
-        (8, 1, "Emancipation Day"),
         (11, 30, "Independance Day"),
+        (12, 26, "Boxing Day"),  # Not the same as UK Boxing Day
     )
 
     def get_kadooment_day(self, year):
@@ -32,14 +38,31 @@ class Barbados(WesternCalendar):
         return (Barbados.get_nth_weekday_in_month(year, 8, MON),
                 "Kadooment Day")
 
+    def get_emancipation_day(self, year):
+        emancipation_day = date(year, 8, 1)
+        if emancipation_day.weekday() == SUN:
+            emancipation_day += timedelta(days=1)
+        kadooment_day = self.get_kadooment_day(year)
+        if emancipation_day == kadooment_day[0]:
+            emancipation_day += timedelta(days=1)
+        return (emancipation_day, "Emancipation Day")
+
     def get_variable_days(self, year):
         """
         Return variable holidays of the Barbados calendar.
         """
         days = super().get_variable_days(year)
         days.append(self.get_kadooment_day(year))
+        days.append(self.get_emancipation_day(year))
+        non_computable = self.non_computable_holiday(year)
+        if non_computable:
+            days.extend(non_computable)
         return days
 
+    def non_computable_holiday(self, year):
+        non_computable = self.non_computable_holiday_dict.get(year, None)
+        return non_computable
+
     def get_fixed_holidays(self, year):
         """
         Return fixed holidays of the Barbados calendar.


Test patch:
diff --git a/workalendar/tests/test_america.py b/workalendar/tests/test_america.py
index d7f17b5..f0c7efe 100644
--- a/workalendar/tests/test_america.py
+++ b/workalendar/tests/test_america.py
@@ -1,8 +1,8 @@
 from datetime import date
+
+from ..america import (Argentina, Barbados, Chile, Colombia, Mexico, Panama,
+                       Paraguay)
 from . import GenericCalendarTest
-from ..america import (
-    Argentina, Barbados, Chile, Colombia, Mexico, Panama, Paraguay
-)
 
 
 class ArgentinaTest(GenericCalendarTest):
@@ -380,6 +380,22 @@ class BarbadosTest(GenericCalendarTest):
         self.assertIn(date(2009, 12, 25), holidays)  # Christmas Day
         self.assertIn(date(2009, 12, 26), holidays)  # Boxing Day
 
+    def test_holidays_2016(self):
+        holidays = self.cal.holidays_set(2016)
+        self.assertIn(date(2016, 1, 1), holidays)
+        self.assertIn(date(2016, 1, 21), holidays)  # Errol Barrow Day
+        self.assertIn(date(2016, 3, 25), holidays)  # Good Friday
+        self.assertIn(date(2016, 3, 28), holidays)  # Easter Monday
+        self.assertIn(date(2016, 4, 28), holidays)  # National Heroes Day
+        self.assertIn(date(2016, 5, 2), holidays)  # Labour Day
+        self.assertIn(date(2016, 5, 16), holidays)  # Whit Monday
+        self.assertIn(date(2016, 8, 1), holidays)  # Kabooment Day
+        self.assertIn(date(2016, 8, 2), holidays)  # Emancipation Day
+        self.assertIn(date(2016, 11, 30), holidays)  # Independant Day
+        self.assertIn(date(2016, 12, 25), holidays)  # Christmas Day
+        self.assertIn(date(2016, 12, 26), holidays)  # Boxing Day
+        self.assertIn(date(2016, 12, 27), holidays)  # Public Holiday
+
     def test_holidays_2018(self):
         holidays = self.cal.holidays_set(2018)
         self.assertIn(date(2018, 1, 1), holidays)
@@ -416,3 +432,39 @@ class BarbadosTest(GenericCalendarTest):
         self.assertIn(date(2019, 11, 30), holidays)  # Independant Day
         self.assertIn(date(2019, 12, 25), holidays)  # Christmas Day
         self.assertIn(date(2019, 12, 26), holidays)  # Boxing Day
+
+    def test_holidays_2020(self):
+        holidays = self.cal.holidays_set(2020)
+        self.assertIn(date(2020, 1, 1), holidays)
+        self.assertIn(date(2020, 1, 21), holidays)  # Errol Barrow Day
+        self.assertIn(date(2020, 4, 10), holidays)  # Good Friday
+        self.assertIn(date(2020, 4, 13), holidays)  # Easter Monday
+
+        # National Heroes Day & shift
+        self.assertIn(date(2020, 4, 28), holidays)
+
+        self.assertIn(date(2020, 5, 1), holidays)  # Labour Day
+        self.assertIn(date(2020, 6, 1), holidays)  # Whit Monday
+        self.assertIn(date(2020, 8, 1), holidays)  # Emancipation Day
+        self.assertIn(date(2020, 8, 3), holidays)  # Kabooment Day
+        self.assertIn(date(2020, 11, 30), holidays)  # Independant Day
+        self.assertIn(date(2020, 12, 25), holidays)  # Christmas Day
+        self.assertIn(date(2020, 12, 26), holidays)  # Boxing Day
+
+    def test_holidays_2021(self):
+        holidays = self.cal.holidays_set(2021)
+        self.assertIn(date(2021, 1, 1), holidays)  # New Year's Day
+        self.assertIn(date(2021, 1, 4), holidays)  # Public Holiday
+        self.assertIn(date(2021, 1, 5), holidays)  # Public Holiday
+        self.assertIn(date(2021, 1, 21), holidays)  # Errol Barrow Day
+        self.assertIn(date(2021, 4, 2), holidays)  # Good Friday
+        self.assertIn(date(2021, 4, 5), holidays)  # Easter Monday
+        self.assertIn(date(2021, 4, 28), holidays)  # National Heroes Day
+
+        self.assertIn(date(2021, 5, 1), holidays)  # Labour Day
+        self.assertIn(date(2021, 5, 24), holidays)  # Whit Monday
+        self.assertIn(date(2021, 8, 2), holidays)  # Kabooment Day
+        self.assertIn(date(2021, 8, 3), holidays)  # Emancipation Day
+        self.assertIn(date(2021, 11, 30), holidays)  # Independant Day
+        self.assertIn(date(2021, 12, 25), holidays)  # Christmas Day
+        self.assertIn(date(2021, 12, 27), holidays)  # Boxing Day