Repository: vacanza/python-holidays

Issue:
Spain Holidays that fall on Sunday are passed to Monday always
This year there are two days that fall on Sunday:

- 2020-11-01 Todos los Santos
- 2020-12-06 Día de la constitución Española

These days are not holidays. Right dates are:
- 2020-11-02 Todos los Santos
- 2020-12-07 Día de la constitución Española

More info in https://www.qppstudio.net/publicholidays2020/spain.htm


Discussion:
Please check my comments on #310 ..
Thank you!
dr-p
No updates on this: closing, thx
dr-p
Sorry @dr-prodigy I have recently had a baby, so no time to opensource.

In a close future, when i have time, i will open a new issue regarding this again.

I hope you understand it.

Resolving patch:
diff --git a/holidays/countries/spain.py b/holidays/countries/spain.py
--- a/holidays/countries/spain.py
+++ b/holidays/countries/spain.py
@@ -17,6 +17,7 @@
 from dateutil.relativedelta import relativedelta as rd, TH, FR, MO
 from holidays.constants import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP,\
     OCT, NOV, DEC
+from holidays.constants import SUN
 from holidays.holiday_base import HolidayBase
 
 
@@ -29,81 +30,97 @@ def __init__(self, **kwargs):
         self.prov = kwargs.pop('prov', kwargs.pop('state', ''))
         HolidayBase.__init__(self, **kwargs)
 
+    def _is_observed(self, date_holiday, name_holiday):
+        if self.observed and date_holiday.weekday() == SUN:
+            self[date_holiday + rd(days=+1)] = name_holiday + " (Trasladado)"
+        else:
+            self[date_holiday] = name_holiday
+
     def _populate(self, year):
-        self[date(year, JAN, 1)] = "Año nuevo"
-        self[date(year, JAN, 6)] = "Epifanía del Señor"
+        self._is_observed(date(year, JAN, 1), "Año nuevo")
+        self._is_observed(date(year, JAN, 6), "Epifanía del Señor")
 
         if year < 2015 and self.prov and self.prov in \
                 ['AR', 'CL', 'CM', 'EX', 'GA', 'MD', 'ML', 'MC', 'NC',
                  'PV', 'VC']:
-            self[date(year, MAR, 19)] = "San José"
+            self._is_observed(date(year, MAR, 19), "San José")
         elif year == 2015 and self.prov and self.prov in \
                 ['CM', 'MD', 'ML', 'MC', 'NC', 'PV', 'VC']:
-            self[date(year, MAR, 19)] = "San José"
+            self._is_observed(date(year, MAR, 19), "San José")
         elif year == 2016 and self.prov and self.prov in \
                 ['ML', 'MC', 'PV', 'VC']:
-            self[date(year, MAR, 19)] = "San José"
+            self._is_observed(date(year, MAR, 19), "San José")
         elif year == 2017 and self.prov and self.prov in ['PV']:
-            self[date(year, MAR, 19)] = "San José"
+            self._is_observed(date(year, MAR, 19), "San José")
         elif 2018 <= year <= 2019 and self.prov and self.prov in \
                 ['GA', 'MC', 'NC', 'PV', 'VC']:
-            self[date(year, MAR, 19)] = "San José"
+            self._is_observed(date(year, MAR, 19), "San José")
         elif 2020 <= year <= 2025 and self.prov and self.prov in \
                 ['CM', 'GA', 'MC', 'NC', 'PV', 'VC']:
-            self[date(year, MAR, 19)] = "San José"
+            self._is_observed(date(year, MAR, 19), "San José")
         if self.prov and self.prov not in ['CT', 'VC']:
             self[easter(year) + rd(weeks=-1, weekday=TH)] = "Jueves Santo"
             self[easter(year) + rd(weeks=-1, weekday=FR)] = "Viernes Santo"
         if self.prov and self.prov in \
                 ['CT', 'PV', 'NC', 'VC', 'IB', 'CM']:
             self[easter(year) + rd(weekday=MO)] = "Lunes de Pascua"
-        self[date(year, MAY, 1)] = "Día del Trabajador"
+        self._is_observed(date(year, MAY, 1), "Día del Trabajador")
         if self.prov and self.prov in ['CT', 'GA', 'VC']:
-            self[date(year, JUN, 24)] = "San Juan"
-        self[date(year, AUG, 15)] = "Asunción de la Virgen"
-        self[date(year, OCT, 12)] = "Día de la Hispanidad"
-        self[date(year, NOV, 1)] = "Todos los Santos"
-        self[date(year, DEC, 6)] = "Día de la constitución Española"
-        self[date(year, DEC, 8)] = "La Inmaculada Concepción"
-        self[date(year, DEC, 25)] = "Navidad"
+            self._is_observed(date(year, JUN, 24), "San Juan")
+        self._is_observed(date(year, AUG, 15), "Asunción de la Virgen")
+        self._is_observed(date(year, OCT, 12), "Día de la Hispanidad")
+        self._is_observed(date(year, NOV, 1), "Todos los Santos")
+        self._is_observed(date(year, DEC, 6), "Día de la Constitución "
+                                              "Española")
+        self._is_observed(date(year, DEC, 8), "La Inmaculada Concepción")
+        self._is_observed(date(year, DEC, 25), "Navidad")
         if self.prov and self.prov in ['CT', 'IB']:
-            self[date(year, DEC, 26)] = "San Esteban"
+            self._is_observed(date(year, DEC, 26), "San Esteban")
         # Provinces festive day
         if self.prov:
             if self.prov == 'AN':
-                self[date(year, FEB, 28)] = "Día de Andalucia"
+                self._is_observed(date(year, FEB, 28), "Día de Andalucia")
             elif self.prov == 'AR':
-                self[date(year, APR, 23)] = "Día de San Jorge"
+                self._is_observed(date(year, APR, 23), "Día de San Jorge")
             elif self.prov == 'AS':
-                self[date(year, SEP, 8)] = "Día de Asturias"
+                self._is_observed(date(year, SEP, 8), "Día de Asturias")
             elif self.prov == 'CB':
-                self[date(year, FEB, 28)] = "Día de la Montaña"
+                self._is_observed(date(year, JUL, 28), "Día de las Instituci"
+                                                       "ones de Cantabria")
             elif self.prov == 'CM':
-                self[date(year, FEB, 28)] = "Día de Castilla - La Mancha"
+                self._is_observed(date(year, MAY, 31), "Día de Castilla "
+                                                       "La Mancha")
             elif self.prov == 'CL':
-                self[date(year, APR, 23)] = "Día de Castilla y Leon"
+                self._is_observed(date(year, APR, 23), "Día de Castilla y "
+                                                       "Leon")
             elif self.prov == 'CT':
-                self[date(year, SEP, 11)] = "Día Nacional de Catalunya"
+                self._is_observed(date(year, SEP, 11), "Día Nacional de "
+                                                       "Catalunya")
             elif self.prov == 'VC':
-                self[date(year, OCT, 9)] = "Día de la Comunidad Valenciana"
+                self._is_observed(date(year, OCT, 9), "Día de la Comunidad "
+                                                      "Valenciana")
             elif self.prov == 'EX':
-                self[date(year, SEP, 8)] = "Día de Extremadura"
+                self._is_observed(date(year, SEP, 8), "Día de Extremadura")
             elif self.prov == 'GA':
-                self[date(year, JUL, 25)] = "Día Nacional de Galicia"
+                self._is_observed(date(year, JUL, 25), "Día Nacional de "
+                                                       "Galicia")
             elif self.prov == 'IB':
-                self[date(year, MAR, 1)] = "Día de las Islas Baleares"
+                self._is_observed(date(year, MAR, 1), "Día de las Islas "
+                                                      "Baleares")
             elif self.prov == 'CN':
-                self[date(year, MAY, 30)] = "Día de Canarias"
+                self._is_observed(date(year, MAY, 30), "Día de Canarias")
             elif self.prov == 'MD':
-                self[date(year, MAY, 2)] = "Día de Comunidad De Madrid"
+                self._is_observed(date(year, MAY, 2), "Día de Comunidad de "
+                                                      "Madrid")
             elif self.prov == 'MC':
-                self[date(year, JUN, 9)] = "Día de la Región de Murcia"
+                self._is_observed(date(year, JUN, 9), "Día de la Región de "
+                                                      "Murcia")
             elif self.prov == 'NC':
-                self[date(year, SEP, 27)] = "Día de Navarra"
+                self._is_observed(date(year, SEP, 27), "Día de Navarra")
             elif self.prov == 'PV':
-                self[date(year, OCT, 25)] = "Día del Páis Vasco"
+                self._is_observed(date(year, OCT, 25), "Día del Páis Vasco")
             elif self.prov == 'RI':
-                self[date(year, JUN, 9)] = "Día de La Rioja"
+                self._is_observed(date(year, JUN, 9), "Día de La Rioja")
 
 
 class ES(Spain):


Test patch:
diff --git a/tests.py b/tests.py
--- a/tests.py
+++ b/tests.py
@@ -3196,8 +3196,9 @@ def test_2020(self):
 class TestES(unittest.TestCase):
 
     def setUp(self):
-        self.holidays = holidays.ES()
-        self.prov_holidays = {prov: holidays.ES(prov=prov)
+        self.holidays = holidays.ES(observed=False)
+        self.holidays_observed = holidays.ES()
+        self.prov_holidays = {prov: holidays.ES(observed=False, prov=prov)
                               for prov in holidays.ES.PROVINCES}
 
     def test_fixed_holidays(self):
@@ -3215,6 +3216,21 @@ def test_fixed_holidays(self):
         for y, (m, d) in product(range(1950, 2050), fixed_days_whole_country):
             self.assertIn(date(y, m, d), self.holidays)
 
+    def test_fixed_holidays_observed(self):
+        fixed_days_whole_country = (
+            (1, 1),
+            (1, 6),
+            (5, 1),
+            (8, 15),
+            (10, 12),
+            (11, 2),
+            (12, 7),
+            (12, 8),
+            (12, 25),
+        )
+        for (m, d) in fixed_days_whole_country:
+            self.assertIn(date(2020, m, d), self.holidays_observed)
+
     def test_variable_days_in_2016(self):
         for prov, prov_holidays in self.prov_holidays.items():
             self.assertEqual(
@@ -3229,13 +3245,15 @@ def test_variable_days_in_2016(self):
 
     def test_province_specific_days(self):
         province_days = {
-            (2, 28): ['AN', 'CB', 'CM'],
+            (2, 28): ['AN'],
             (3, 1): ['IB'],
             (4, 23): ['AR', 'CL'],
             (5, 30): ['CN'],
+            (5, 31): ['CM'],
             (5, 2): ['MD'],
             (6, 9): ['MC', 'RI'],
             (7, 25): ['GA'],
+            (7, 28): ['CB'],
             (9, 8): ['AS', 'EX'],
             (9, 11): ['CT'],
             (9, 27): ['NC'],