Skip to content

BUG: incorrectly defined Memoridal Day holiday #9763

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

BUG: incorrectly defined Memoridal Day holiday #9763

wants to merge 1 commit into from

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