Skip to content

Conversation

@zegres
Copy link

@zegres zegres commented Mar 31, 2015

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')

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')
@jreback
Copy link
Contributor

jreback commented Apr 2, 2015

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))

@jreback jreback added the Bug label Apr 2, 2015
@zegres
Copy link
Author

zegres commented Apr 2, 2015

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:

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.

@jreback jreback added this to the 0.16.1 milestone Apr 4, 2015
@jreback
Copy link
Contributor

jreback commented Apr 4, 2015

@zegres

  • can you add a release note in v0.16.1.txt
  • can you add a test

@jreback
Copy link
Contributor

jreback commented Apr 17, 2015

@zegres can you update

@jreback jreback modified the milestones: 0.17.0, 0.16.1 Apr 28, 2015
@jreback
Copy link
Contributor

jreback commented May 9, 2015

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

@jreback jreback added the Datetime Datetime data dtype label May 9, 2015
@jreback jreback changed the title Update holiday.py BUG: incorrectly defined Memoridal Day holiday May 9, 2015
@jreback
Copy link
Contributor

jreback commented Jul 28, 2015

can you update?

@jreback
Copy link
Contributor

jreback commented Aug 12, 2015

closing in favor of #10282

@jreback jreback closed this Aug 12, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Datetime Datetime data dtype

Projects

None yet

Development

Successfully merging this pull request may close these issues.

USMemorialDay defined incorrectly.

2 participants