Repository: peopledoc/workalendar (python)

Issue:
"Family Day" Date error? (Subdivision: CA-BC / 2020 +)
Your project appears to return Family Day as the second Monday in February in British Columbia 

It appears from https://news.gov.bc.ca/releases/2018PREM0018-000188 that Family Day in British Columbia has been shifted to the third Monday in February from 2020.



Pull request:
Fix Family Day computation for British Columbia (Canada)
closes #454

It fixes two things:

* Family Day was introduced in 2013, workalendar was assuming it was there before
* In 2019, Family Day was moved from the 2nd to the 3rd MON of February

- [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.*


Patch:
diff --git a/Changelog.md b/Changelog.md
index c79dfe5..eb69884 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,7 +2,7 @@
 
 ## master (unreleased)
 
-Nothing here yet.
+- Fix Family Day for British Columbia (Canada) which was switched from 2nd to 3rd Monday of February in 2019 - thx @jbroudou for the bug report (#454).
 
 ## v8.0.0 (2020-01-10)
 
diff --git a/workalendar/america/canada.py b/workalendar/america/canada.py
index 7c61e6c..ad6b397 100644
--- a/workalendar/america/canada.py
+++ b/workalendar/america/canada.py
@@ -31,13 +31,6 @@ class Canada(WesternCalendar, ChristianMixin):
         return days
 
 
-class EarlyFamilyDayMixin(Calendar):
-    "2nd Monday of February"
-
-    def get_family_day(self, year, label="Family Day"):
-        return (self.get_nth_weekday_in_month(year, 2, MON, 2), label)
-
-
 class LateFamilyDayMixin(Calendar):
     "3rd Monday of February"
 
@@ -148,7 +141,7 @@ class Quebec(Canada, VictoriaDayMixin, StJeanBaptisteMixin, ThanksgivingMixin):
 
 @iso_register('CA-BC')
 class BritishColumbia(Canada, VictoriaDayMixin, AugustCivicHolidayMixin,
-                      ThanksgivingMixin, EarlyFamilyDayMixin):
+                      ThanksgivingMixin):
     "British Columbia"
 
     include_good_friday = True
@@ -157,10 +150,24 @@ class BritishColumbia(Canada, VictoriaDayMixin, AugustCivicHolidayMixin,
         (11, 11, "Remembrance Day"),
     )
 
+    def get_family_day(self, year):
+        """
+        Return Family Day for British Columbia.
+
+        From 2013 to 2018, Family Day was on 2nd MON of February
+        As of 2019, Family Day happens on 3rd MON of February
+        """
+        label = "Family Day"
+        if year >= 2019:
+            return (self.get_nth_weekday_in_month(year, 2, MON, 3), label)
+        return (self.get_nth_weekday_in_month(year, 2, MON, 2), label)
+
     def get_variable_days(self, year):
         days = super().get_variable_days(year)
+        if year >= 2013:
+            days.append(self.get_family_day(year))
+
         days.extend([
-            (self.get_family_day(year)),
             (self.get_victoria_day(year)),
             (self.get_civic_holiday(year, "British Columbia Day")),
             (self.get_thanksgiving(year)),


Test patch:
diff --git a/workalendar/tests/test_canada.py b/workalendar/tests/test_canada.py
index 5798940..e18cad3 100644
--- a/workalendar/tests/test_canada.py
+++ b/workalendar/tests/test_canada.py
@@ -1,5 +1,6 @@
 from datetime import date
 from . import GenericCalendarTest
+from ..core import MON
 from ..america.canada import (
     Canada, Ontario, Quebec, BritishColumbia, Alberta, Saskatchewan, Manitoba,
     NewBrunswick, NovaScotia, PrinceEdwardIsland, Newfoundland, Yukon,
@@ -97,7 +98,9 @@ class BritishColumbiaTest(GenericCalendarTest):
     def test_holidays_2012(self):
         holidays = self.cal.holidays_set(2012)
         self.assertIn(date(2012, 1, 2), holidays)
-        self.assertIn(date(2012, 2, 13), holidays)  # Family Day BC
+        # Family Day BC was not set in 2012
+        self.assertNotIn(date(2012, 2, 13), holidays)
+
         self.assertIn(date(2012, 4, 6), holidays)  # Good Friday
         self.assertNotIn(date(2012, 4, 9), holidays)  # Easter Monday
         self.assertIn(date(2012, 5, 21), holidays)  # Victoria Day
@@ -108,6 +111,21 @@ class BritishColumbiaTest(GenericCalendarTest):
         self.assertIn(date(2012, 11, 11), holidays)  # Remembrance Day
         self.assertIn(date(2012, 12, 25), holidays)  # Christmas day
 
+    def test_family_day(self):
+        # From 2013 to 2018, Family Day was on 2nd MON of February
+        for year in range(2013, 2019):
+            holidays = dict(self.cal.holidays(year))
+            day = self.cal.get_nth_weekday_in_month(year, 2, MON, 2)
+            self.assertIn(day, holidays)
+            self.assertEqual(holidays[day], "Family Day")
+
+        # As of 2019, it happens on 3rd MON of February
+        for year in (2019, 2020, 2021):
+            holidays = dict(self.cal.holidays(year))
+            day = self.cal.get_nth_weekday_in_month(year, 2, MON, 3)
+            self.assertIn(day, holidays)
+            self.assertEqual(holidays[day], "Family Day")
+
 
 class AlbertaTest(GenericCalendarTest):
     cal_class = Alberta