BUG: incorrectly defined Memoridal Day holiday
State: closed

closes #9760 

Memorial Day was incorrectly defined.
It is the last Monday in May, so the earliest it could be is the 25th (not the 24th).
This change fixes the problem.

```
>>> from pandas.tseries.holiday import AbstractHolidayCalendar, USMemorialDay
>>> class MemorialDayCalendar(AbstractHolidayCalendar):rules=[USMemorialDay]
>>> MemorialDayCalendar().holidays('2021','2022')
```

Will now return Timestamp('2021-05-31 00:00:00') instead of Timestamp('2021-05-24 00:00:00')


Labels:
name: Bug
name: Datetime
description: Datetime data dtype

Comments:
cc @rockg

this is not right either. 

memorial day as an example is defined as the last monday in may. IIRC you had the ability to define things like that.

This is somewhat old (and function/methods different), but how I used to do this:

```
# US Holidays

class US(dates.Holidays):
        def add_dates(self):
                year = self.year

                self.add_new_years_day(year)
                self.add_date(name = "Martin Luther King Birthday", date = self.date_for(year,1,day_of=3,weekday='Monday'))
                if year >= 2007:
                        self.add_date(name = "US DST Start",   date = self.date_for(year,3,day_of=2,weekday='Sunday'), type = 'info')
                        self.add_date(name = "US DST End"  ,   date = self.date_for(year,11,day_of=1,weekday='Sunday'), type = 'info')
                else:
                        self.add_date(name = "US DST Start",   date = self.date_for(year,4,day_of=1,weekday='Sunday'), type = 'info')
                        self.add_date(name = "US DST End"  ,   date = self.date_for(year,10,day_of=5,weekday='Sunday'), type = 'info')
                self.add_date(name = "Presidents Day"        , date = self.date_for(year,2,day_of=3,weekday='Monday'))
                self.add_good_friday(year)
                self.add_easter_sunday(year)
                self.add_date(name = "Memorial Day"          , date = self.date_for(year,5,day_of=5,weekday='Monday'))
                self.add_date(name = "Independence Day Before" , date = self.date_for(year,7,3).nearest_workday(), type = 'early')
                self.add_date(name = "Independence Day"      , date = self.date_for(year,7,4).nearest_workday())
                #self.add_date(name = "Independence Day Before" , date = self.date_for(year,7,3).nearest_workday(), type = 'early')
                self.add_date(name = "Labor Day"             , date = self.date_for(year,9,day_of=1,weekday='Monday'))
                self.add_date(name = "Thanksgiving"          , date = self.date_for(year,11,day_of=4,weekday='Thursday'))
                self.add_date(name = "Thanksgiving Day After", date = self.date_for(year,11,day_of=4,weekday='Thursday',mod=1), type = 'early')
                self.add_date(name = "Christmas Day Before"  , date = self.date_for(year,12,24).nearest_workday(), type = 'early')
                self.add_christmas(year)

                # hurricane sandy
                if year == 2012:
                        self.add_date(name = "Hurricane Sandy Day 1", date = self.date_for(2012,10,29))
                        self.add_date(name = "Hurricane Sandy Day 2", date = self.date_for(2012,10,30))
```

The solution in my pull request is correct.
It is also the easiest way to get Memorial Day right (only changing one number).

If you would like to verify that it is correct, here is a test for 500 years:

``` python
from pandas import DataFrame, Timestamp, period_range
from pandas.tseries.holiday import AbstractHolidayCalendar, USMemorialDay, MO, Holiday
from pandas.tseries.offsets import DateOffset
from numpy import logical_and
from datetime import datetime

class MemorialDayCalendar(AbstractHolidayCalendar):
    rules=[Holiday('Memorial Day', month=5 , day=25, offset=DateOffset(weekday=MO(1))),]
all_dates = period_range('1700','2200',freq='D')
all_may_mondays = all_dates[logical_and(all_dates.month==5, all_dates.dayofweek==0)]
check_last_monday = DataFrame({'Day':all_may_mondays.day, 'Year':all_may_mondays.year})
last_mondays = check_last_monday.groupby('Year').max()
actual_memorial_days = [datetime(year=year, month=5, day=day)
                        for year,day in last_mondays.Day.iteritems()]
generated_memorial_days = MemorialDayCalendar().holidays(start='1700',end='2200')\
                                               .to_pydatetime().tolist()
actual_memorial_days == generated_memorial_days
```

Returns True.

@zegres 
- can you add a release note in v0.16.1.txt 
- can you add a test

@zegres can you update

@zegres would have been nice to include this, but we need to have a test.

can you update?

closing in favor of #10282