diff --git a/pandas/tseries/holiday.py b/pandas/tseries/holiday.py index 3b3542b760d6f..c31e25115c6a4 100644 --- a/pandas/tseries/holiday.py +++ b/pandas/tseries/holiday.py @@ -203,7 +203,10 @@ def dates(self, start_date, end_date, return_name=False): end_date = Timestamp(end_date) year_offset = DateOffset(years=1) - base_date = Timestamp(datetime(start_date.year, self.month, self.day)) + base_date = Timestamp( + datetime(start_date.year, self.month, self.day), + tz=start_date.tz, + ) dates = DatetimeIndex(start=base_date, end=end_date, freq=year_offset) holiday_dates = self._apply_rule(dates) if self.days_of_week is not None: diff --git a/pandas/tseries/tests/test_holiday.py b/pandas/tseries/tests/test_holiday.py index c2300481eca43..0880e84f1fcde 100644 --- a/pandas/tseries/tests/test_holiday.py +++ b/pandas/tseries/tests/test_holiday.py @@ -9,6 +9,7 @@ HolidayCalendarFactory, next_workday, previous_workday, before_nearest_workday, EasterMonday, GoodFriday, after_nearest_workday, weekend_to_monday) +from pytz import utc import nose class TestCalendar(tm.TestCase): @@ -55,87 +56,119 @@ def setUp(self): self.start_date = datetime(2011, 1, 1) self.end_date = datetime(2020, 12, 31) + def check_results(self, holiday, start, end, expected): + self.assertEqual(list(holiday.dates(start, end)), expected) + # Verify that timezone info is preserved. + self.assertEqual( + list( + holiday.dates( + utc.localize(Timestamp(start)), + utc.localize(Timestamp(end)), + ) + ), + [utc.localize(dt) for dt in expected], + ) + def test_usmemorialday(self): - holidays = USMemorialDay.dates(self.start_date, - self.end_date) - holidayList = [ - datetime(2011, 5, 30), - datetime(2012, 5, 28), - datetime(2013, 5, 27), - datetime(2014, 5, 26), - datetime(2015, 5, 25), - datetime(2016, 5, 30), - datetime(2017, 5, 29), - datetime(2018, 5, 28), - datetime(2019, 5, 27), - datetime(2020, 5, 25), - ] - self.assertEqual(list(holidays), holidayList) + self.check_results( + holiday=USMemorialDay, + start=self.start_date, + end=self.end_date, + expected=[ + datetime(2011, 5, 30), + datetime(2012, 5, 28), + datetime(2013, 5, 27), + datetime(2014, 5, 26), + datetime(2015, 5, 25), + datetime(2016, 5, 30), + datetime(2017, 5, 29), + datetime(2018, 5, 28), + datetime(2019, 5, 27), + datetime(2020, 5, 25), + ], + ) def test_non_observed_holiday(self): - july_3rd = Holiday('July 4th Eve', month=7, day=3) - result = july_3rd.dates("2001-01-01", "2003-03-03") - expected = [Timestamp('2001-07-03 00:00:00'), - Timestamp('2002-07-03 00:00:00')] - self.assertEqual(list(result), expected) - july_3rd = Holiday('July 4th Eve', month=7, day=3, - days_of_week=(0, 1, 2, 3)) - result = july_3rd.dates("2001-01-01", "2008-03-03") - expected = [Timestamp('2001-07-03 00:00:00'), - Timestamp('2002-07-03 00:00:00'), - Timestamp('2003-07-03 00:00:00'), - Timestamp('2006-07-03 00:00:00'), - Timestamp('2007-07-03 00:00:00')] - self.assertEqual(list(result), expected) + + self.check_results( + Holiday('July 4th Eve', month=7, day=3), + start="2001-01-01", + end="2003-03-03", + expected=[ + Timestamp('2001-07-03 00:00:00'), + Timestamp('2002-07-03 00:00:00') + ] + ) + + self.check_results( + Holiday('July 4th Eve', month=7, day=3, days_of_week=(0, 1, 2, 3)), + start="2001-01-01", + end="2008-03-03", + expected=[ + Timestamp('2001-07-03 00:00:00'), + Timestamp('2002-07-03 00:00:00'), + Timestamp('2003-07-03 00:00:00'), + Timestamp('2006-07-03 00:00:00'), + Timestamp('2007-07-03 00:00:00'), + ] + ) def test_easter(self): - holidays = EasterMonday.dates(self.start_date, - self.end_date) - holidayList = [Timestamp('2011-04-25 00:00:00'), - Timestamp('2012-04-09 00:00:00'), - Timestamp('2013-04-01 00:00:00'), - Timestamp('2014-04-21 00:00:00'), - Timestamp('2015-04-06 00:00:00'), - Timestamp('2016-03-28 00:00:00'), - Timestamp('2017-04-17 00:00:00'), - Timestamp('2018-04-02 00:00:00'), - Timestamp('2019-04-22 00:00:00'), - Timestamp('2020-04-13 00:00:00')] - - - self.assertEqual(list(holidays), holidayList) - holidays = GoodFriday.dates(self.start_date, - self.end_date) - holidayList = [Timestamp('2011-04-22 00:00:00'), - Timestamp('2012-04-06 00:00:00'), - Timestamp('2013-03-29 00:00:00'), - Timestamp('2014-04-18 00:00:00'), - Timestamp('2015-04-03 00:00:00'), - Timestamp('2016-03-25 00:00:00'), - Timestamp('2017-04-14 00:00:00'), - Timestamp('2018-03-30 00:00:00'), - Timestamp('2019-04-19 00:00:00'), - Timestamp('2020-04-10 00:00:00')] - self.assertEqual(list(holidays), holidayList) - + + self.check_results( + EasterMonday, + start=self.start_date, + end=self.end_date, + expected=[ + Timestamp('2011-04-25 00:00:00'), + Timestamp('2012-04-09 00:00:00'), + Timestamp('2013-04-01 00:00:00'), + Timestamp('2014-04-21 00:00:00'), + Timestamp('2015-04-06 00:00:00'), + Timestamp('2016-03-28 00:00:00'), + Timestamp('2017-04-17 00:00:00'), + Timestamp('2018-04-02 00:00:00'), + Timestamp('2019-04-22 00:00:00'), + Timestamp('2020-04-13 00:00:00'), + ], + ) + self.check_results( + GoodFriday, + start=self.start_date, + end=self.end_date, + expected=[ + Timestamp('2011-04-22 00:00:00'), + Timestamp('2012-04-06 00:00:00'), + Timestamp('2013-03-29 00:00:00'), + Timestamp('2014-04-18 00:00:00'), + Timestamp('2015-04-03 00:00:00'), + Timestamp('2016-03-25 00:00:00'), + Timestamp('2017-04-14 00:00:00'), + Timestamp('2018-03-30 00:00:00'), + Timestamp('2019-04-19 00:00:00'), + Timestamp('2020-04-10 00:00:00'), + ], + ) def test_usthanksgivingday(self): - holidays = USThanksgivingDay.dates(self.start_date, - self.end_date) - holidayList = [ - datetime(2011, 11, 24), - datetime(2012, 11, 22), - datetime(2013, 11, 28), - datetime(2014, 11, 27), - datetime(2015, 11, 26), - datetime(2016, 11, 24), - datetime(2017, 11, 23), - datetime(2018, 11, 22), - datetime(2019, 11, 28), - datetime(2020, 11, 26), - ] - - self.assertEqual(list(holidays), holidayList) + + self.check_results( + USThanksgivingDay, + start=self.start_date, + end=self.end_date, + expected=[ + datetime(2011, 11, 24), + datetime(2012, 11, 22), + datetime(2013, 11, 28), + datetime(2014, 11, 27), + datetime(2015, 11, 26), + datetime(2016, 11, 24), + datetime(2017, 11, 23), + datetime(2018, 11, 22), + datetime(2019, 11, 28), + datetime(2020, 11, 26), + ], + ) def test_argument_types(self): holidays = USThanksgivingDay.dates(self.start_date,