Repository: peopledoc/workalendar (python)

Issue:
Wrong UnitedKingdom holidays for 2012
workalendar==4.0.0 from PYPI
python 3.6 on LINUX

Hi, thanks for this library that is exactly what I'm looking for. 
One issue I have is with holidays in the UK that seem to be wrong for years when the government "randomly" decided to add some. The last example is the Queen’s Diamond Jubilee.
Here is the official link: https://www.gov.uk/bank-holidays with 2012 at the end of the page.

The great thing about this year is:
- There is an additional bank holiday on June 5
- The usual Spring bank holiday is **not** the last Monday of May (May 28) but  June 4.

I don't have a complete list (yet) but there are other years with similar holiday like 2002.

Are these holiday something you see being in the scope of workalendar? 
I'll probably fork your repo to manage them anyway so I'm interested to know if you are open to a PR to manage these cases. If it's the case there may be a way you prefer me to go to manage this. 

Bellow the code I run with the missing and wrong date:

    from workalendar.europe import UnitedKingdom 
    cal = UnitedKingdom()
    cal.holidays(2012)

Gives me:
    [(datetime.date(2012, 1, 1), 'New year'),
     (datetime.date(2012, 1, 2), 'New Year shift'),
     (datetime.date(2012, 4, 6), 'Good Friday'),
     (datetime.date(2012, 4, 8), 'Easter Sunday'),
     (datetime.date(2012, 4, 9), 'Easter Monday'),
     (datetime.date(2012, 5, 7), 'Early May Bank Holiday'),
     (datetime.date(2012, 5, 28), 'Spring Bank Holiday'),
     (datetime.date(2012, 8, 27), 'Late Summer Bank Holiday'),
     (datetime.date(2012, 12, 25), 'Christmas Day'),
     (datetime.date(2012, 12, 26), 'Boxing Day')]

Thanks.

Pull request:
Fix 2012 and 2002 UK holiday.
closes #315 

<!-- 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.


Patch:
diff --git a/Changelog.md b/Changelog.md
index 68aa605..9faddb6 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,7 +2,10 @@
 
 ## master (unreleased)
 
-Nothing here yet.
+### Bugfixes
+
+- Fixed United Kingdom bank holiday for 2002 and 2012.
+
 
 ## 4.0.0 (2019-01-24)
 
diff --git a/workalendar/europe/united_kingdom.py b/workalendar/europe/united_kingdom.py
index 81610f1..f90d62c 100644
--- a/workalendar/europe/united_kingdom.py
+++ b/workalendar/europe/united_kingdom.py
@@ -15,6 +15,10 @@ class UnitedKingdom(WesternCalendar, ChristianMixin):
     include_easter_monday = True
     include_boxing_day = True
     shift_new_years_day = True
+    non_computable_holiday_dict = {
+        2002: [(date(2002, 6, 3), "Queen’s Golden Jubilee"), ],
+        2012: [(date(2012, 6, 5), "Queen’s Diamond Jubilee"), ],
+    }
 
     def get_early_may_bank_holiday(self, year):
         return (
@@ -23,8 +27,15 @@ class UnitedKingdom(WesternCalendar, ChristianMixin):
         )
 
     def get_spring_bank_holiday(self, year):
+        if year == 2012:
+            spring_bank_holiday = date(2012, 6, 4)
+        elif year == 2002:
+            spring_bank_holiday = date(2002, 6, 4)
+        else:
+            spring_bank_holiday = UnitedKingdom \
+                .get_last_weekday_in_month(year, 5, MON)
         return (
-            UnitedKingdom.get_last_weekday_in_month(year, 5, MON),
+            spring_bank_holiday,
             "Spring Bank Holiday"
         )
 
@@ -34,6 +45,10 @@ class UnitedKingdom(WesternCalendar, ChristianMixin):
             "Late Summer Bank Holiday"
         )
 
+    def non_computable_holiday(self, year):
+        non_computable = self.non_computable_holiday_dict.get(year, None)
+        return non_computable
+
     def get_variable_days(self, year):
         days = super(UnitedKingdom, self).get_variable_days(year)
         days.append(self.get_early_may_bank_holiday(year))
@@ -42,6 +57,9 @@ class UnitedKingdom(WesternCalendar, ChristianMixin):
         # Boxing day & XMas shift
         shifts = self.shift_christmas_boxing_days(year=year)
         days.extend(shifts)
+        non_computable = self.non_computable_holiday(year)
+        if non_computable:
+            days.extend(non_computable)
         return days
 
 


Test patch:
diff --git a/workalendar/tests/test_europe.py b/workalendar/tests/test_europe.py
index 26e2247..36048e3 100644
--- a/workalendar/tests/test_europe.py
+++ b/workalendar/tests/test_europe.py
@@ -707,6 +707,33 @@ class UnitedKingdomTest(GenericCalendarTest):
         self.assertIn(date(2013, 12, 25), holidays)  # Christmas
         self.assertIn(date(2013, 12, 26), holidays)  # Boxing Day
 
+    def test_year_2002(self):
+        holidays = self.cal.holidays_set(2002)
+        self.assertIn(date(2002, 1, 1), holidays)  # new year day
+        self.assertIn(date(2002, 3, 29), holidays)  # good friday
+        self.assertIn(date(2002, 3, 31), holidays)  # easter sunday
+        self.assertIn(date(2002, 4, 1), holidays)  # easter monday
+        self.assertIn(date(2002, 5, 6), holidays)  # Early May Bank Holiday
+        self.assertIn(date(2002, 6, 3), holidays)  # queen's golden jubilee
+        self.assertIn(date(2002, 6, 4), holidays)  # Spring Bank Holiday
+        self.assertIn(date(2002, 8, 26), holidays)  # Late Summer Bank Holiday
+        self.assertIn(date(2002, 12, 25), holidays)  # Christmas
+        self.assertIn(date(2002, 12, 26), holidays)  # Boxing Day
+
+    def test_year_2012(self):
+        holidays = self.cal.holidays_set(2012)
+        self.assertIn(date(2012, 1, 1), holidays)  # new year day
+        self.assertIn(date(2012, 1, 2), holidays)  # new year shift
+        self.assertIn(date(2012, 4, 6), holidays)  # good friday
+        self.assertIn(date(2012, 4, 8), holidays)  # easter sunday
+        self.assertIn(date(2012, 4, 9), holidays)  # easter monday
+        self.assertIn(date(2012, 5, 7), holidays)  # Early May Bank Holiday
+        self.assertIn(date(2012, 6, 4), holidays)  # Spring Bank Holiday
+        self.assertIn(date(2012, 6, 5), holidays)  # queen's diamond jubilee
+        self.assertIn(date(2012, 8, 27), holidays)  # Late Summer Bank Holiday
+        self.assertIn(date(2012, 12, 25), holidays)  # Christmas
+        self.assertIn(date(2012, 12, 26), holidays)  # Boxing Day
+
     def test_shift_2012(self):
         holidays = self.cal.holidays_set(2012)
         self.assertIn(date(2012, 1, 1), holidays)  # new year day