class TimestampOps(object): params = [None, 'US/Eastern', pytz.UTC, dateutil.tz.tzutc()] param_names = ['tz'] def setup(self, tz): self.ts = Timestamp('2017-08-25 08:16:14', tz=tz) def time_replace_tz(self, tz): self.ts.replace(tzinfo=pytz.timezone('US/Eastern')) def time_replace_None(self, tz): self.ts.replace(tzinfo=None) def time_to_pydatetime(self, tz): self.ts.to_pydatetime() def time_normalize(self, tz): self.ts.normalize() def time_tz_convert(self, tz): if self.ts.tz is not None: self.ts.tz_convert(tz) def time_tz_localize(self, tz): if self.ts.tz is None: self.ts.tz_localize(tz)
def test_timestamp_tz_localize_nonexistent_raise(self, tz): # GH 8917 ts = Timestamp('2015-03-29 02:20:00') with pytest.raises(pytz.NonExistentTimeError): ts.tz_localize(tz, nonexistent='raise') with pytest.raises(ValueError): ts.tz_localize(tz, nonexistent='foo')
def test_tz_localize_errors_invalid_arg(self): # GH 22644 tz = 'Europe/Warsaw' ts = Timestamp('2015-03-29 02:00:00') with pytest.raises(ValueError): with tm.assert_produces_warning(FutureWarning): ts.tz_localize(tz, errors='foo')
def test_tz_localize_nonexistent(self, stamp, tz): # GH#13057 ts = Timestamp(stamp) with pytest.raises(NonExistentTimeError): ts.tz_localize(tz) with pytest.raises(NonExistentTimeError): ts.tz_localize(tz, errors='raise') assert ts.tz_localize(tz, errors='coerce') is NaT
def test_timestamp_tz_localize_nonexistent_shift_invalid(self, offset, tz_type): # GH 8917, 24466 tz = tz_type + 'Europe/Warsaw' ts = Timestamp('2015-03-29 02:20:00') msg = "The provided timedelta will relocalize on a nonexistent time" with pytest.raises(ValueError, match=msg): ts.tz_localize(tz, nonexistent=timedelta(seconds=offset))
def test_tz_localize_errors_coerce(self): # GH 22644 # make sure errors='coerce' gets mapped correctly to nonexistent tz = 'Europe/Warsaw' ts = Timestamp('2015-03-29 02:00:00') with tm.assert_produces_warning(FutureWarning): result = ts.tz_localize(tz, errors='coerce') expected = ts.tz_localize(tz, nonexistent='NaT') assert result is expected
def test_tz_localize_nonexistent(self, stamp, tz): # GH#13057 ts = Timestamp(stamp) with pytest.raises(NonExistentTimeError): ts.tz_localize(tz) # GH 22644 with pytest.raises(NonExistentTimeError): with tm.assert_produces_warning(FutureWarning): ts.tz_localize(tz, errors='raise') with tm.assert_produces_warning(FutureWarning): assert ts.tz_localize(tz, errors='coerce') is NaT
def test_tz_localize_ambiguous_bool(self): # make sure that we are correctly accepting bool values as ambiguous # GH#14402 ts = Timestamp('2015-11-01 01:00:03') expected0 = Timestamp('2015-11-01 01:00:03-0500', tz='US/Central') expected1 = Timestamp('2015-11-01 01:00:03-0600', tz='US/Central') with pytest.raises(pytz.AmbiguousTimeError): ts.tz_localize('US/Central') result = ts.tz_localize('US/Central', ambiguous=True) assert result == expected0 result = ts.tz_localize('US/Central', ambiguous=False) assert result == expected1
def test_timestamp_tz_localize_explicit(self): stamp = Timestamp("3/11/2012 04:00") result = stamp.tz_localize(self.tz("US/Eastern")) expected = Timestamp("3/11/2012 04:00", tz=self.tz("US/Eastern")) self.assertEqual(result.hour, expected.hour) self.assertEqual(result, expected)
def test_timestamp_tz_localize(self, tz): stamp = Timestamp('3/11/2012 04:00') result = stamp.tz_localize(tz) expected = Timestamp('3/11/2012 04:00', tz=tz) assert result.hour == expected.hour assert result == expected
def test_timestamp_tz_localize(self): stamp = Timestamp('3/11/2012 04:00') result = stamp.tz_localize('US/Eastern') expected = Timestamp('3/11/2012 04:00', tz='US/Eastern') self.assertEquals(result.hour, expected.hour) self.assertEquals(result, expected)
def test_timestamp_constructor_near_dst_boundary(self): # GH#11481 & GH#15777 # Naive string timestamps were being localized incorrectly # with tz_convert_single instead of tz_localize_to_utc for tz in ['Europe/Brussels', 'Europe/Prague']: result = Timestamp('2015-10-25 01:00', tz=tz) expected = Timestamp('2015-10-25 01:00').tz_localize(tz) assert result == expected with pytest.raises(pytz.AmbiguousTimeError): Timestamp('2015-10-25 02:00', tz=tz) result = Timestamp('2017-03-26 01:00', tz='Europe/Paris') expected = Timestamp('2017-03-26 01:00').tz_localize('Europe/Paris') assert result == expected with pytest.raises(pytz.NonExistentTimeError): Timestamp('2017-03-26 02:00', tz='Europe/Paris') # GH#11708 naive = Timestamp('2015-11-18 10:00:00') result = naive.tz_localize('UTC').tz_convert('Asia/Kolkata') expected = Timestamp('2015-11-18 15:30:00+0530', tz='Asia/Kolkata') assert result == expected # GH#15823 result = Timestamp('2017-03-26 00:00', tz='Europe/Paris') expected = Timestamp('2017-03-26 00:00:00+0100', tz='Europe/Paris') assert result == expected result = Timestamp('2017-03-26 01:00', tz='Europe/Paris') expected = Timestamp('2017-03-26 01:00:00+0100', tz='Europe/Paris') assert result == expected with pytest.raises(pytz.NonExistentTimeError): Timestamp('2017-03-26 02:00', tz='Europe/Paris') result = Timestamp('2017-03-26 02:00:00+0100', tz='Europe/Paris') naive = Timestamp(result.value) expected = naive.tz_localize('UTC').tz_convert('Europe/Paris') assert result == expected result = Timestamp('2017-03-26 03:00', tz='Europe/Paris') expected = Timestamp('2017-03-26 03:00:00+0200', tz='Europe/Paris') assert result == expected
def test_tz(self): tstr = '2014-02-01 09:00' ts = Timestamp(tstr) local = ts.tz_localize('Asia/Tokyo') assert local.hour == 9 assert local == Timestamp(tstr, tz='Asia/Tokyo') conv = local.tz_convert('US/Eastern') assert conv == Timestamp('2014-01-31 19:00', tz='US/Eastern') assert conv.hour == 19 # preserves nanosecond ts = Timestamp(tstr) + offsets.Nano(5) local = ts.tz_localize('Asia/Tokyo') assert local.hour == 9 assert local.nanosecond == 5 conv = local.tz_convert('US/Eastern') assert conv.nanosecond == 5 assert conv.hour == 19
def test_tz(self): tstr = "2014-02-01 09:00" ts = Timestamp(tstr) local = ts.tz_localize("Asia/Tokyo") assert local.hour == 9 assert local == Timestamp(tstr, tz="Asia/Tokyo") conv = local.tz_convert("US/Eastern") assert conv == Timestamp("2014-01-31 19:00", tz="US/Eastern") assert conv.hour == 19 # preserves nanosecond ts = Timestamp(tstr) + offsets.Nano(5) local = ts.tz_localize("Asia/Tokyo") assert local.hour == 9 assert local.nanosecond == 5 conv = local.tz_convert("US/Eastern") assert conv.nanosecond == 5 assert conv.hour == 19
def pandas_timestamp_as_eastern(dt: pd.Timestamp) -> pd.Timestamp: """ convert a pandas date as a tz-aware datetime """ if dt == None: return None if type(dt) != pd.Timestamp: raise Exception(f"type ({type(dt)}) is not pandas.TimeStamp") if dt.tzname() != None: raise Exception(f"value ({dt}) is not a naive timestamp") return dt.tz_localize(eastern_tz)
def test_tz_localize_ambiguous(self): ts = Timestamp('2014-11-02 01:00') ts_dst = ts.tz_localize('US/Eastern', ambiguous=True) ts_no_dst = ts.tz_localize('US/Eastern', ambiguous=False) assert (ts_no_dst.value - ts_dst.value) / 1e9 == 3600 with pytest.raises(ValueError): ts.tz_localize('US/Eastern', ambiguous='infer') # GH#8025 msg = ('Cannot localize tz-aware Timestamp, ' 'use tz_convert for conversions') with pytest.raises(TypeError, match=msg): Timestamp('2011-01-01', tz='US/Eastern').tz_localize('Asia/Tokyo') msg = ('Cannot convert tz-naive Timestamp, ' 'use tz_localize to localize') with pytest.raises(TypeError, match=msg): Timestamp('2011-01-01').tz_convert('Asia/Tokyo')
def test_timestamp_tz_localize_nonexistent_shift(self, start_ts, tz, end_ts, shift, tz_type): # GH 8917, 24466 tz = tz_type + tz if isinstance(shift, str): shift = "shift_" + shift ts = Timestamp(start_ts) result = ts.tz_localize(tz, nonexistent=shift) expected = Timestamp(end_ts).tz_localize(tz) assert result == expected
def test_tz_localize_ambiguous(self): ts = Timestamp('2014-11-02 01:00') ts_dst = ts.tz_localize('US/Eastern', ambiguous=True) ts_no_dst = ts.tz_localize('US/Eastern', ambiguous=False) assert (ts_no_dst.value - ts_dst.value) / 1e9 == 3600 with pytest.raises(ValueError): ts.tz_localize('US/Eastern', ambiguous='infer') # GH#8025 with tm.assert_raises_regex(TypeError, 'Cannot localize tz-aware Timestamp, ' 'use tz_convert for conversions'): Timestamp('2011-01-01', tz='US/Eastern').tz_localize('Asia/Tokyo') with tm.assert_raises_regex(TypeError, 'Cannot convert tz-naive Timestamp, ' 'use tz_localize to localize'): Timestamp('2011-01-01').tz_convert('Asia/Tokyo')
def test_timestamp_tz_localize_nonexistent_shift(self, start_ts, tz, end_ts, shift, tz_type): # GH 8917, 24466 tz = tz_type + tz if isinstance(shift, str): shift = 'shift_' + shift ts = Timestamp(start_ts) result = ts.tz_localize(tz, nonexistent=shift) expected = Timestamp(end_ts).tz_localize(tz) assert result == expected
def test_tz_localize_roundtrip(self, stamp, tz): ts = Timestamp(stamp) localized = ts.tz_localize(tz) assert localized == Timestamp(stamp, tz=tz) with pytest.raises(TypeError): localized.tz_localize(tz) reset = localized.tz_localize(None) assert reset == ts assert reset.tzinfo is None
def test_describe_with_tz(self, tz_naive_fixture): # GH 21332 tz = tz_naive_fixture name = str(tz_naive_fixture) start = Timestamp(2018, 1, 1) end = Timestamp(2018, 1, 5) s = Series(date_range(start, end, tz=tz), name=name) result = s.describe() expected = Series( [ 5, 5, s.value_counts().index[0], 1, start.tz_localize(tz), end.tz_localize(tz), ], name=name, index=["count", "unique", "top", "freq", "first", "last"], ) tm.assert_series_equal(result, expected)
def test_describe_tz_values2(self): tz = "CET" s1 = Series(range(5)) start = Timestamp(2018, 1, 1) end = Timestamp(2018, 1, 5) s2 = Series(date_range(start, end, tz=tz)) df = DataFrame({"s1": s1, "s2": s2}) s1_ = s1.describe() s2_ = Series( [ 5, 5, s2.value_counts().index[0], 1, start.tz_localize(tz), end.tz_localize(tz), ], index=["count", "unique", "top", "freq", "first", "last"], ) idx = [ "count", "unique", "top", "freq", "first", "last", "mean", "std", "min", "25%", "50%", "75%", "max", ] expected = pd.concat([s1_, s2_], axis=1, keys=["s1", "s2"]).loc[idx] with tm.assert_produces_warning(FutureWarning): result = df.describe(include="all") tm.assert_frame_equal(result, expected)
def test_describe_with_tz_warns(self): name = tz = "CET" start = Timestamp(2018, 1, 1) end = Timestamp(2018, 1, 5) s = Series(date_range(start, end, tz=tz), name=name) with tm.assert_produces_warning(FutureWarning): result = s.describe() expected = Series( [ 5, 5, s.value_counts().index[0], 1, start.tz_localize(tz), end.tz_localize(tz), ], name=name, index=["count", "unique", "top", "freq", "first", "last"], ) tm.assert_series_equal(result, expected)
def test_describe_with_tz(self, tz_naive_fixture): # GH 21332 tz = tz_naive_fixture name = str(tz_naive_fixture) start = Timestamp(2018, 1, 1) end = Timestamp(2018, 1, 5) s = Series(date_range(start, end, tz=tz), name=name) result = s.describe(datetime_is_numeric=True) expected = Series( [ 5, Timestamp(2018, 1, 3).tz_localize(tz), start.tz_localize(tz), s[1], s[2], s[3], end.tz_localize(tz), ], name=name, index=["count", "mean", "min", "25%", "50%", "75%", "max"], ) tm.assert_series_equal(result, expected)
def test_tz_localize_roundtrip(self, stamp, tz_aware_fixture): tz = tz_aware_fixture ts = Timestamp(stamp) localized = ts.tz_localize(tz) assert localized == Timestamp(stamp, tz=tz) msg = "Cannot localize tz-aware Timestamp" with pytest.raises(TypeError, match=msg): localized.tz_localize(tz) reset = localized.tz_localize(None) assert reset == ts assert reset.tzinfo is None
def test_tz_localize_ambiguous_compat(self): # validate that pytz and dateutil are compat for dst # when the transition happens naive = Timestamp('2013-10-27 01:00:00') pytz_zone = 'Europe/London' dateutil_zone = 'dateutil/Europe/London' result_pytz = naive.tz_localize(pytz_zone, ambiguous=0) result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=0) assert result_pytz.value == result_dateutil.value assert result_pytz.value == 1382835600000000000 if LooseVersion(dateutil.__version__) < LooseVersion('2.6.0'): # dateutil 2.6 buggy w.r.t. ambiguous=0 # see gh-14621 # see https://github.com/dateutil/dateutil/issues/321 assert (result_pytz.to_pydatetime().tzname() == result_dateutil.to_pydatetime().tzname()) assert str(result_pytz) == str(result_dateutil) elif LooseVersion(dateutil.__version__) > LooseVersion('2.6.0'): # fixed ambiguous behavior assert result_pytz.to_pydatetime().tzname() == 'GMT' assert result_dateutil.to_pydatetime().tzname() == 'BST' assert str(result_pytz) != str(result_dateutil) # 1 hour difference result_pytz = naive.tz_localize(pytz_zone, ambiguous=1) result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=1) assert result_pytz.value == result_dateutil.value assert result_pytz.value == 1382832000000000000 # dateutil < 2.6 is buggy w.r.t. ambiguous timezones if LooseVersion(dateutil.__version__) > LooseVersion('2.5.3'): # see gh-14621 assert str(result_pytz) == str(result_dateutil) assert (result_pytz.to_pydatetime().tzname() == result_dateutil.to_pydatetime().tzname())
def test_constructor_coverage(self): # float value for periods expected = pd.interval_range(start=0, periods=10) result = pd.interval_range(start=0, periods=10.5) tm.assert_index_equal(result, expected) # equivalent timestamp-like start/end start, end = Timestamp('2017-01-01'), Timestamp('2017-01-15') expected = pd.interval_range(start=start, end=end) result = pd.interval_range(start=start.to_pydatetime(), end=end.to_pydatetime()) tm.assert_index_equal(result, expected) result = pd.interval_range(start=start.tz_localize('UTC'), end=end.tz_localize('UTC')) tm.assert_index_equal(result, expected) result = pd.interval_range(start=start.asm8, end=end.asm8) tm.assert_index_equal(result, expected) # equivalent freq with timestamp equiv_freq = [ 'D', Day(), Timedelta(days=1), timedelta(days=1), DateOffset(days=1) ] for freq in equiv_freq: result = pd.interval_range(start=start, end=end, freq=freq) tm.assert_index_equal(result, expected) # equivalent timedelta-like start/end start, end = Timedelta(days=1), Timedelta(days=10) expected = pd.interval_range(start=start, end=end) result = pd.interval_range(start=start.to_pytimedelta(), end=end.to_pytimedelta()) tm.assert_index_equal(result, expected) result = pd.interval_range(start=start.asm8, end=end.asm8) tm.assert_index_equal(result, expected) # equivalent freq with timedelta equiv_freq = ['D', Day(), Timedelta(days=1), timedelta(days=1)] for freq in equiv_freq: result = pd.interval_range(start=start, end=end, freq=freq) tm.assert_index_equal(result, expected)
def test_today(self): ts_from_string = Timestamp('today') ts_from_method = Timestamp.today() ts_datetime = datetime.today() ts_from_string_tz = Timestamp('today', tz='US/Eastern') ts_from_method_tz = Timestamp.today(tz='US/Eastern') # Check that the delta between the times is less than 1s (arbitrarily # small) delta = Timedelta(seconds=1) assert abs(ts_from_method - ts_from_string) < delta assert abs(ts_datetime - ts_from_method) < delta assert abs(ts_from_method_tz - ts_from_string_tz) < delta assert (abs(ts_from_string_tz.tz_localize(None) - ts_from_method_tz.tz_localize(None)) < delta)
def timestamp_tzaware(timestamp): """ Returns the pandas Timestamp passed as a timezone (UTC) aware Timestamp. Args: timestamp (pandas.Timestamp): Timezone naive Timestamp Returns: pandas.Timestamp: Timezone aware """ from pandas import Timestamp if not isinstance(timestamp, Timestamp): timestamp = Timestamp(timestamp) if timestamp.tzinfo is None: return timestamp.tz_localize(tz="UTC") else: return timestamp.tz_convert(tz="UTC")
def test_now(self): # GH#9000 ts_from_string = Timestamp("now") ts_from_method = Timestamp.now() ts_datetime = datetime.now() ts_from_string_tz = Timestamp("now", tz="US/Eastern") ts_from_method_tz = Timestamp.now(tz="US/Eastern") # Check that the delta between the times is less than 1s (arbitrarily # small) delta = Timedelta(seconds=1) assert abs(ts_from_method - ts_from_string) < delta assert abs(ts_datetime - ts_from_method) < delta assert abs(ts_from_method_tz - ts_from_string_tz) < delta assert (abs( ts_from_string_tz.tz_localize(None) - ts_from_method_tz.tz_localize(None)) < delta)
def test_constructor_coverage(self): # float value for periods expected = pd.interval_range(start=0, periods=10) result = pd.interval_range(start=0, periods=10.5) tm.assert_index_equal(result, expected) # equivalent timestamp-like start/end start, end = Timestamp('2017-01-01'), Timestamp('2017-01-15') expected = pd.interval_range(start=start, end=end) result = pd.interval_range(start=start.to_pydatetime(), end=end.to_pydatetime()) tm.assert_index_equal(result, expected) result = pd.interval_range(start=start.tz_localize('UTC'), end=end.tz_localize('UTC')) tm.assert_index_equal(result, expected) result = pd.interval_range(start=start.asm8, end=end.asm8) tm.assert_index_equal(result, expected) # equivalent freq with timestamp equiv_freq = ['D', Day(), Timedelta(days=1), timedelta(days=1), DateOffset(days=1)] for freq in equiv_freq: result = pd.interval_range(start=start, end=end, freq=freq) tm.assert_index_equal(result, expected) # equivalent timedelta-like start/end start, end = Timedelta(days=1), Timedelta(days=10) expected = pd.interval_range(start=start, end=end) result = pd.interval_range(start=start.to_pytimedelta(), end=end.to_pytimedelta()) tm.assert_index_equal(result, expected) result = pd.interval_range(start=start.asm8, end=end.asm8) tm.assert_index_equal(result, expected) # equivalent freq with timedelta equiv_freq = ['D', Day(), Timedelta(days=1), timedelta(days=1)] for freq in equiv_freq: result = pd.interval_range(start=start, end=end, freq=freq) tm.assert_index_equal(result, expected)
def create_aligned_timestamp(time): """ Align the passed datetime / Timestamp object to the minute interval for use in dateranges and overlap checks. Args: time (str, pandas.Timestamp) Returns: pandas.Timestamp: Timestamp aligned to minute with UTC timezone """ from pandas import Timedelta, Timestamp if not isinstance(time, Timestamp): time = Timestamp(ts_input=time) if time.tzinfo is None: t = time.tz_localize(tz="UTC") else: t = time.tz_convert(tz="UTC") t -= Timedelta(f"{t.second} s") return t
def test_tz_conversion_freq(self, tz_naive_fixture): # GH25241 t1 = Timestamp('2019-01-01 10:00', freq='H') assert t1.tz_localize(tz=tz_naive_fixture).freq == t1.freq t2 = Timestamp('2019-01-02 12:00', tz='UTC', freq='T') assert t2.tz_convert(tz='UTC').freq == t2.freq
def test_timestamp_tz_localize_nonexistent_NaT(self, tz): # GH 8917 ts = Timestamp("2015-03-29 02:20:00") result = ts.tz_localize(tz, nonexistent="NaT") assert result is NaT
def test_tz_localize_errors_ambiguous(self): # GH#13057 ts = Timestamp('2015-11-1 01:00') with pytest.raises(AmbiguousTimeError): ts.tz_localize('US/Pacific', errors='coerce')
def test_tz_localize_ambiguous_raise(self): # GH#13057 ts = Timestamp("2015-11-1 01:00") msg = "Cannot infer dst time from 2015-11-01 01:00:00," with pytest.raises(AmbiguousTimeError, match=msg): ts.tz_localize("US/Pacific", ambiguous="raise")
def test_replace_tzinfo_equiv_tz_localize_none(self): # GH#14621, GH#7825 # assert conversion to naive is the same as replacing tzinfo with None ts = Timestamp('2013-11-03 01:59:59.999999-0400', tz='US/Eastern') assert ts.tz_localize(None) == ts.replace(tzinfo=None)
class Holiday: """ Class that defines a holiday with start/end dates and rules for observance. """ def __init__( self, name, year=None, month=None, day=None, offset=None, observance=None, start_date=None, end_date=None, days_of_week=None, ): """ Parameters ---------- name : str Name of the holiday , defaults to class name offset : array of pandas.tseries.offsets or class from pandas.tseries.offsets computes offset from date observance: function computes when holiday is given a pandas Timestamp days_of_week: provide a tuple of days e.g (0,1,2,3,) for Monday Through Thursday Monday=0,..,Sunday=6 Examples -------- >>> from dateutil.relativedelta import MO >>> USMemorialDay = pd.tseries.holiday.Holiday( ... "Memorial Day", month=5, day=31, offset=pd.DateOffset(weekday=MO(-1)) ... ) >>> USMemorialDay Holiday: Memorial Day (month=5, day=31, offset=<DateOffset: weekday=MO(-1)>) >>> USLaborDay = pd.tseries.holiday.Holiday( ... "Labor Day", month=9, day=1, offset=pd.DateOffset(weekday=MO(1)) ... ) >>> USLaborDay Holiday: Labor Day (month=9, day=1, offset=<DateOffset: weekday=MO(+1)>) >>> July3rd = pd.tseries.holiday.Holiday("July 3rd", month=7, day=3) >>> July3rd Holiday: July 3rd (month=7, day=3, ) >>> NewYears = pd.tseries.holiday.Holiday( ... "New Years Day", month=1, day=1, ... observance=pd.tseries.holiday.nearest_workday ... ) >>> NewYears # doctest: +SKIP Holiday: New Years Day ( month=1, day=1, observance=<function nearest_workday at 0x66545e9bc440> ) >>> July3rd = pd.tseries.holiday.Holiday( ... "July 3rd", month=7, day=3, ... days_of_week=(0, 1, 2, 3) ... ) >>> July3rd Holiday: July 3rd (month=7, day=3, ) """ if offset is not None and observance is not None: raise NotImplementedError("Cannot use both offset and observance.") self.name = name self.year = year self.month = month self.day = day self.offset = offset self.start_date = (Timestamp(start_date) if start_date is not None else start_date) self.end_date = Timestamp( end_date) if end_date is not None else end_date self.observance = observance assert days_of_week is None or type(days_of_week) == tuple self.days_of_week = days_of_week def __repr__(self) -> str: info = "" if self.year is not None: info += f"year={self.year}, " info += f"month={self.month}, day={self.day}, " if self.offset is not None: info += f"offset={self.offset}" if self.observance is not None: info += f"observance={self.observance}" repr = f"Holiday: {self.name} ({info})" return repr def dates(self, start_date, end_date, return_name=False): """ Calculate holidays observed between start date and end date Parameters ---------- start_date : starting date, datetime-like, optional end_date : ending date, datetime-like, optional return_name : bool, optional, default=False If True, return a series that has dates and holiday names. False will only return dates. """ start_date = Timestamp(start_date) end_date = Timestamp(end_date) filter_start_date = start_date filter_end_date = end_date if self.year is not None: dt = Timestamp(datetime(self.year, self.month, self.day)) if return_name: return Series(self.name, index=[dt]) else: return [dt] dates = self._reference_dates(start_date, end_date) holiday_dates = self._apply_rule(dates) if self.days_of_week is not None: holiday_dates = holiday_dates[np.in1d(holiday_dates.dayofweek, self.days_of_week)] if self.start_date is not None: filter_start_date = max( self.start_date.tz_localize(filter_start_date.tz), filter_start_date) if self.end_date is not None: filter_end_date = min( self.end_date.tz_localize(filter_end_date.tz), filter_end_date) holiday_dates = holiday_dates[(holiday_dates >= filter_start_date) & (holiday_dates <= filter_end_date)] if return_name: return Series(self.name, index=holiday_dates) return holiday_dates def _reference_dates(self, start_date, end_date): """ Get reference dates for the holiday. Return reference dates for the holiday also returning the year prior to the start_date and year following the end_date. This ensures that any offsets to be applied will yield the holidays within the passed in dates. """ if self.start_date is not None: start_date = self.start_date.tz_localize(start_date.tz) if self.end_date is not None: end_date = self.end_date.tz_localize(start_date.tz) year_offset = DateOffset(years=1) reference_start_date = Timestamp( datetime(start_date.year - 1, self.month, self.day)) reference_end_date = Timestamp( datetime(end_date.year + 1, self.month, self.day)) # Don't process unnecessary holidays dates = date_range( start=reference_start_date, end=reference_end_date, freq=year_offset, tz=start_date.tz, ) return dates def _apply_rule(self, dates): """ Apply the given offset/observance to a DatetimeIndex of dates. Parameters ---------- dates : DatetimeIndex Dates to apply the given offset/observance rule Returns ------- Dates with rules applied """ if self.observance is not None: return dates.map(lambda d: self.observance(d)) if self.offset is not None: if not isinstance(self.offset, list): offsets = [self.offset] else: offsets = self.offset for offset in offsets: # if we are adding a non-vectorized value # ignore the PerformanceWarnings: with warnings.catch_warnings(): warnings.simplefilter("ignore", PerformanceWarning) dates += offset return dates
class Holiday(object): """ Class that defines a holiday with start/end dates and rules for observance. """ def __init__(self, name, year=None, month=None, day=None, offset=None, observance=None, start_date=None, end_date=None, days_of_week=None): """ Parameters ---------- name : str Name of the holiday , defaults to class name offset : array of pandas.tseries.offsets or class from pandas.tseries.offsets computes offset from date observance: function computes when holiday is given a pandas Timestamp days_of_week: provide a tuple of days e.g (0,1,2,3,) for Monday Through Thursday Monday=0,..,Sunday=6 Examples -------- >>> from pandas.tseries.holiday import Holiday, nearest_workday >>> from pandas import DateOffset >>> from dateutil.relativedelta import MO >>> USMemorialDay = Holiday('MemorialDay', month=5, day=24, offset=DateOffset(weekday=MO(1))) >>> USLaborDay = Holiday('Labor Day', month=9, day=1, offset=DateOffset(weekday=MO(1))) >>> July3rd = Holiday('July 3rd', month=7, day=3,) >>> NewYears = Holiday('New Years Day', month=1, day=1, observance=nearest_workday), >>> July3rd = Holiday('July 3rd', month=7, day=3, days_of_week=(0, 1, 2, 3)) """ if offset is not None and observance is not None: raise NotImplementedError("Cannot use both offset and observance.") self.name = name self.year = year self.month = month self.day = day self.offset = offset self.start_date = Timestamp( start_date) if start_date is not None else start_date self.end_date = Timestamp( end_date) if end_date is not None else end_date self.observance = observance assert (days_of_week is None or type(days_of_week) == tuple) self.days_of_week = days_of_week def __repr__(self): info = '' if self.year is not None: info += 'year=%s, ' % self.year info += 'month=%s, day=%s, ' % (self.month, self.day) if self.offset is not None: info += 'offset=%s' % self.offset if self.observance is not None: info += 'observance=%s' % self.observance repr = 'Holiday: %s (%s)' % (self.name, info) return repr def dates(self, start_date, end_date, return_name=False): """ Calculate holidays observed between start date and end date Parameters ---------- start_date : starting date, datetime-like, optional end_date : ending date, datetime-like, optional return_name : bool, optional, default=False If True, return a series that has dates and holiday names. False will only return dates. """ start_date = Timestamp(start_date) end_date = Timestamp(end_date) filter_start_date = start_date filter_end_date = end_date if self.year is not None: dt = Timestamp(datetime(self.year, self.month, self.day)) if return_name: return Series(self.name, index=[dt]) else: return [dt] dates = self._reference_dates(start_date, end_date) holiday_dates = self._apply_rule(dates) if self.days_of_week is not None: holiday_dates = holiday_dates[np.in1d(holiday_dates.dayofweek, self.days_of_week)] if self.start_date is not None: filter_start_date = max( self.start_date.tz_localize(filter_start_date.tz), filter_start_date) if self.end_date is not None: filter_end_date = min( self.end_date.tz_localize(filter_end_date.tz), filter_end_date) holiday_dates = holiday_dates[(holiday_dates >= filter_start_date) & (holiday_dates <= filter_end_date)] if return_name: return Series(self.name, index=holiday_dates) return holiday_dates def _reference_dates(self, start_date, end_date): """ Get reference dates for the holiday. Return reference dates for the holiday also returning the year prior to the start_date and year following the end_date. This ensures that any offsets to be applied will yield the holidays within the passed in dates. """ if self.start_date is not None: start_date = self.start_date.tz_localize(start_date.tz) if self.end_date is not None: end_date = self.end_date.tz_localize(start_date.tz) year_offset = DateOffset(years=1) reference_start_date = Timestamp( datetime(start_date.year - 1, self.month, self.day)) reference_end_date = Timestamp( datetime(end_date.year + 1, self.month, self.day)) # Don't process unnecessary holidays dates = DatetimeIndex(start=reference_start_date, end=reference_end_date, freq=year_offset, tz=start_date.tz) return dates def _apply_rule(self, dates): """ Apply the given offset/observance to a DatetimeIndex of dates. Parameters ---------- dates : DatetimeIndex Dates to apply the given offset/observance rule Returns ------- Dates with rules applied """ if self.observance is not None: return dates.map(lambda d: self.observance(d)) if self.offset is not None: if not isinstance(self.offset, list): offsets = [self.offset] else: offsets = self.offset for offset in offsets: # if we are adding a non-vectorized value # ignore the PerformanceWarnings: with warnings.catch_warnings(record=True): dates += offset return dates
def test_timestamp_tz_localize_nonexistent_shift(self, tz): # GH 8917 ts = Timestamp('2015-03-29 02:20:00') result = ts.tz_localize(tz, nonexistent='shift') expected = Timestamp('2015-03-29 03:00:00').tz_localize(tz) assert result == expected
def test_tz_localize_errors_ambiguous(self): # GH#13057 ts = Timestamp('2015-11-1 01:00') with pytest.raises(AmbiguousTimeError): with tm.assert_produces_warning(FutureWarning): ts.tz_localize('US/Pacific', errors='coerce')
def test_tz_localize_ambiguous_raise(self): # GH#13057 ts = Timestamp("2015-11-1 01:00") with pytest.raises(AmbiguousTimeError): ts.tz_localize("US/Pacific", ambiguous="raise")
def test_tz_conversion_freq(self, tz_naive_fixture): # GH25241 t1 = Timestamp("2019-01-01 10:00", freq="H") assert t1.tz_localize(tz=tz_naive_fixture).freq == t1.freq t2 = Timestamp("2019-01-02 12:00", tz="UTC", freq="T") assert t2.tz_convert(tz="UTC").freq == t2.freq
class Holiday(object): """ Class that defines a holiday with start/end dates and rules for observance. """ def __init__(self, name, year=None, month=None, day=None, offset=None, observance=None, start_date=None, end_date=None, days_of_week=None): """ Parameters ---------- name : str Name of the holiday , defaults to class name offset : array of pandas.tseries.offsets or class from pandas.tseries.offsets computes offset from date observance: function computes when holiday is given a pandas Timestamp days_of_week: provide a tuple of days e.g (0,1,2,3,) for Monday Through Thursday Monday=0,..,Sunday=6 Examples -------- >>> from pandas.tseries.holiday import Holiday, nearest_workday >>> from pandas import DateOffset >>> from dateutil.relativedelta import MO >>> USMemorialDay = Holiday('MemorialDay', month=5, day=24, offset=DateOffset(weekday=MO(1))) >>> USLaborDay = Holiday('Labor Day', month=9, day=1, offset=DateOffset(weekday=MO(1))) >>> July3rd = Holiday('July 3rd', month=7, day=3,) >>> NewYears = Holiday('New Years Day', month=1, day=1, observance=nearest_workday), >>> July3rd = Holiday('July 3rd', month=7, day=3, days_of_week=(0, 1, 2, 3)) """ if offset is not None and observance is not None: raise NotImplementedError("Cannot use both offset and observance.") self.name = name self.year = year self.month = month self.day = day self.offset = offset self.start_date = Timestamp( start_date) if start_date is not None else start_date self.end_date = Timestamp( end_date) if end_date is not None else end_date self.observance = observance assert (days_of_week is None or type(days_of_week) == tuple) self.days_of_week = days_of_week def __repr__(self): info = '' if self.year is not None: info += 'year={year}, '.format(year=self.year) info += 'month={mon}, day={day}, '.format(mon=self.month, day=self.day) if self.offset is not None: info += 'offset={offset}'.format(offset=self.offset) if self.observance is not None: info += 'observance={obs}'.format(obs=self.observance) repr = 'Holiday: {name} ({info})'.format(name=self.name, info=info) return repr def dates(self, start_date, end_date, return_name=False): """ Calculate holidays observed between start date and end date Parameters ---------- start_date : starting date, datetime-like, optional end_date : ending date, datetime-like, optional return_name : bool, optional, default=False If True, return a series that has dates and holiday names. False will only return dates. """ start_date = Timestamp(start_date) end_date = Timestamp(end_date) filter_start_date = start_date filter_end_date = end_date if self.year is not None: dt = Timestamp(datetime(self.year, self.month, self.day)) if return_name: return Series(self.name, index=[dt]) else: return [dt] dates = self._reference_dates(start_date, end_date) holiday_dates = self._apply_rule(dates) if self.days_of_week is not None: holiday_dates = holiday_dates[np.in1d(holiday_dates.dayofweek, self.days_of_week)] if self.start_date is not None: filter_start_date = max(self.start_date.tz_localize( filter_start_date.tz), filter_start_date) if self.end_date is not None: filter_end_date = min(self.end_date.tz_localize( filter_end_date.tz), filter_end_date) holiday_dates = holiday_dates[(holiday_dates >= filter_start_date) & (holiday_dates <= filter_end_date)] if return_name: return Series(self.name, index=holiday_dates) return holiday_dates def _reference_dates(self, start_date, end_date): """ Get reference dates for the holiday. Return reference dates for the holiday also returning the year prior to the start_date and year following the end_date. This ensures that any offsets to be applied will yield the holidays within the passed in dates. """ if self.start_date is not None: start_date = self.start_date.tz_localize(start_date.tz) if self.end_date is not None: end_date = self.end_date.tz_localize(start_date.tz) year_offset = DateOffset(years=1) reference_start_date = Timestamp( datetime(start_date.year - 1, self.month, self.day)) reference_end_date = Timestamp( datetime(end_date.year + 1, self.month, self.day)) # Don't process unnecessary holidays dates = DatetimeIndex(start=reference_start_date, end=reference_end_date, freq=year_offset, tz=start_date.tz) return dates def _apply_rule(self, dates): """ Apply the given offset/observance to a DatetimeIndex of dates. Parameters ---------- dates : DatetimeIndex Dates to apply the given offset/observance rule Returns ------- Dates with rules applied """ if self.observance is not None: return dates.map(lambda d: self.observance(d)) if self.offset is not None: if not isinstance(self.offset, list): offsets = [self.offset] else: offsets = self.offset for offset in offsets: # if we are adding a non-vectorized value # ignore the PerformanceWarnings: with warnings.catch_warnings(record=True): dates += offset return dates
def test_tz_localize_nonexistent_invalid_arg(self): # GH 22644 tz = "Europe/Warsaw" ts = Timestamp("2015-03-29 02:00:00") with pytest.raises(ValueError): ts.tz_localize(tz, nonexistent="foo")
class HolidayWithFilter(object): """ Class that defines a holiday with start/end dates and rules for observance. """ def __init__(self, name, year=None, month=None, day=None, offset=None, observance=None, start_date=None, end_date=None, days_of_week=None, year_filter=None, year_mask=None): """ Parameters ---------- name : str Name of the holiday , defaults to class name offset : array of pandas.tseries.offsets or class from pandas.tseries.offsets computes offset from date observance: function computes when holiday is given a pandas Timestamp days_of_week: provide a tuple of days e.g (0,1,2,3,) for Monday Through Thursday Monday=0,..,Sunday=6 """ if offset is not None and observance is not None: raise NotImplementedError("Cannot use both offset and observance.") self.name = name self.year = year self.month = month self.day = day self.offset = offset self.start_date = Timestamp( start_date) if start_date is not None else start_date self.end_date = Timestamp( end_date) if end_date is not None else end_date self.observance = observance assert (days_of_week is None or type(days_of_week) == tuple) self.days_of_week = days_of_week self.year_filter = year_filter self.year_mask = year_mask def __repr__(self): info = '' if self.year is not None: info += 'year={year}, '.format(year=self.year) info += 'month={mon}, day={day}, '.format(mon=self.month, day=self.day) if self.offset is not None: info += 'offset={offset}'.format(offset=self.offset) if self.observance is not None: info += 'observance={obs}'.format(obs=self.observance) if self.year_filter is not None: info += 'year_filter={yrf}'.format(yrf=self.year_filter) if self.year_mask is not None: info += 'year_mask={yrm}'.format(yrf=self.year_mask) repr = 'Holiday: {name} ({info})'.format(name=self.name, info=info) return repr def dates(self, start_date, end_date, return_name=False): """ Calculate holidays observed between start date and end date Parameters ---------- start_date : starting date, datetime-like, optional end_date : ending date, datetime-like, optional return_name : bool, optional, default=False If True, return a series that has dates and holiday names. False will only return dates. """ start_date = Timestamp(start_date) end_date = Timestamp(end_date) filter_start_date = start_date filter_end_date = end_date if self.year is not None: dt = Timestamp(datetime(self.year, self.month, self.day)) if return_name: return Series(self.name, index=[dt]) else: return [dt] dates = self._reference_dates(start_date, end_date) holiday_dates = self._apply_rule(dates) if self.days_of_week is not None: holiday_dates = holiday_dates[np.in1d(holiday_dates.dayofweek, self.days_of_week)] if self.start_date is not None: filter_start_date = max( self.start_date.tz_localize(filter_start_date.tz), filter_start_date) if self.end_date is not None: filter_end_date = min( self.end_date.tz_localize(filter_end_date.tz), filter_end_date) holiday_dates = holiday_dates[(holiday_dates >= filter_start_date) & (holiday_dates <= filter_end_date)] if return_name: return Series(self.name, index=holiday_dates) return holiday_dates def _reference_dates(self, start_date, end_date): """ Get reference dates for the holiday. Return reference dates for the holiday also returning the year prior to the start_date and year following the end_date. This ensures that any offsets to be applied will yield the holidays within the passed in dates. """ if self.start_date is not None: start_date = self.start_date.tz_localize(start_date.tz) if self.end_date is not None: end_date = self.end_date.tz_localize(start_date.tz) year_offset = DateOffset(years=1) reference_start_date = Timestamp( datetime(start_date.year - 1, self.month, self.day)) reference_end_date = Timestamp( datetime(end_date.year + 1, self.month, self.day)) # Don't process unnecessary holidays dates = DatetimeIndex(start=reference_start_date, end=reference_end_date, freq=year_offset, tz=start_date.tz) if self.year_filter is not None: dates = dates[~dates.year.isin(self.year_filter)] if self.year_mask is not None: dates = dates[dates.year.isin(self.year_mask)] return dates def _apply_rule(self, dates): """ Apply the given offset/observance to a DatetimeIndex of dates. Parameters ---------- dates : DatetimeIndex Dates to apply the given offset/observance rule Returns ------- Dates with rules applied """ if self.observance is not None: return dates.map(lambda d: self.observance(d)) if self.offset is not None: if not isinstance(self.offset, list): offsets = [self.offset] else: offsets = self.offset for offset in offsets: # if we are adding a non-vectorized value # ignore the PerformanceWarnings: with warnings.catch_warnings(): warnings.simplefilter("ignore", PerformanceWarning) dates += offset return dates
def test_replace_tzinfo_equiv_tz_localize_none(self): # GH#14621, GH#7825 # assert conversion to naive is the same as replacing tzinfo with None ts = Timestamp("2013-11-03 01:59:59.999999-0400", tz="US/Eastern") assert ts.tz_localize(None) == ts.replace(tzinfo=None)
def test_timestamp_tz_localize_nonexistent_NaT(self, tz): # GH 8917 ts = Timestamp('2015-03-29 02:20:00') result = ts.tz_localize(tz, nonexistent='NaT') assert result is NaT