Repository: peopledoc/workalendar
Pull request #592 (2020-11-13 16:46:59)

Fix Russia New year holidays
The days between 2-5 have become a week off since 2005 (related to #578)


- [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 e462020..3100d28 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -3,6 +3,7 @@
 ## master (unreleased)
 
 - Fix Russia calendar: non-working days are shifted to the next MON when they happen on the week-end (#589).
+- Fix Russia New year holidays. It has become a week off since 2005 (related to #578).
 
 ## v13.0.0 (2020-11-13)
 
diff --git a/workalendar/europe/russia.py b/workalendar/europe/russia.py
index 783854a..2314c17 100644
--- a/workalendar/europe/russia.py
+++ b/workalendar/europe/russia.py
@@ -1,3 +1,5 @@
+from datetime import date
+
 from ..core import OrthodoxCalendar, MON
 from ..registry_tools import iso_register
 
@@ -5,8 +7,6 @@ from ..registry_tools import iso_register
 @iso_register('RU')
 class Russia(OrthodoxCalendar):
     'Russia'
-    shift_new_years_day = True
-
     # Civil holidays
     include_labour_day = True
 
@@ -20,10 +20,26 @@ class Russia(OrthodoxCalendar):
         (11, 4, "Day of Unity"),
     )
 
+    def get_fixed_holidays(self, year):
+        days = super().get_fixed_holidays(year)
+
+        if year >= 2005:
+            days.extend([
+                (date(year, 1, 3), "Third Day after New Year"),
+                (date(year, 1, 4), "Fourth Day after New Year"),
+                (date(year, 1, 5), "Fifth Day after New Year"),
+                (date(year, 1, 6), "Sixth Day after New Year"),
+                (date(year, 1, 8), "Eighth Day after New Year"),
+            ])
+
+        return days
+
     def get_calendar_holidays(self, year):
         holidays = super().get_calendar_holidays(year)
         shifts = []
         for day, label in holidays:
+            if day.month == 1 and day.day in range(1, 9):
+                continue
             if day.weekday() in self.get_weekend_days():
                 shifts.append((
                     self.get_first_weekday_after(day, MON),


Test patch:
diff --git a/workalendar/tests/test_europe.py b/workalendar/tests/test_europe.py
index 073aebd..1dab571 100644
--- a/workalendar/tests/test_europe.py
+++ b/workalendar/tests/test_europe.py
@@ -1437,6 +1437,29 @@ class RussiaTest(GenericCalendarTest):
             "Victory Day shift"
         )
 
+    def test_new_year_holidays_2004(self):
+        # At that time, only Jan 1st/2nd were holidays.
+        holidays = self.cal.holidays_set(2004)
+        self.assertIn(date(2004, 1, 1), holidays)  # New Year's Day
+        self.assertIn(date(2004, 1, 2), holidays)  # Day after New Year
+        self.assertNotIn(date(2004, 1, 3), holidays)  # Shift of Jan 2nd
+        self.assertNotIn(date(2004, 1, 4), holidays)  # Not until 2005
+        self.assertNotIn(date(2004, 1, 5), holidays)  # Not until 2005
+        self.assertNotIn(date(2004, 1, 6), holidays)  # Not until 2005
+        self.assertIn(date(2004, 1, 7), holidays)  # XMas
+        self.assertNotIn(date(2004, 1, 8), holidays)  # Not until 2005
+
+    def test_new_year_holidays_2005(self):
+        holidays = self.cal.holidays_set(2005)
+        self.assertIn(date(2005, 1, 1), holidays)  # New Year's Day
+        self.assertIn(date(2005, 1, 2), holidays)  # Day after New Year
+        self.assertIn(date(2005, 1, 3), holidays)  # Holiday since 2005
+        self.assertIn(date(2005, 1, 4), holidays)  # Holiday since 2005
+        self.assertIn(date(2005, 1, 5), holidays)  # Holiday since 2005
+        self.assertIn(date(2005, 1, 6), holidays)  # Holiday since 2005
+        self.assertIn(date(2005, 1, 7), holidays)  # XMas
+        self.assertIn(date(2005, 1, 8), holidays)  # Part of the holiday week
+
 
 class UkraineTest(GenericCalendarTest):
     cal_class = Ukraine