def test_cache_keys_are_distinct_for_pytz_vs_dateutil(tz_name): if tz_name == 'UTC': # skip utc as it's a special case in dateutil return tz_p = timezones.maybe_get_tz(tz_name) tz_d = timezones.maybe_get_tz('dateutil/' + tz_name) if tz_d is None: # skip timezones that dateutil doesn't know about. return assert timezones._p_tz_cache_key(tz_p) != timezones._p_tz_cache_key(tz_d)
def test_cache_keys_are_distinct_for_pytz_vs_dateutil(tz_name): if tz_name == "UTC": pytest.skip("UTC: special case in dateutil") tz_p = timezones.maybe_get_tz(tz_name) tz_d = timezones.maybe_get_tz("dateutil/" + tz_name) if tz_d is None: pytest.skip(tz_name + ": dateutil does not know about this one") assert timezones._p_tz_cache_key(tz_p) != timezones._p_tz_cache_key(tz_d)
def test_tz_convert_utc_with_system_utc(self): from pandas._libs.tslibs.timezones import maybe_get_tz # from system utc to real utc ts = Timestamp('2001-01-05 11:56', tz=maybe_get_tz('dateutil/UTC')) # check that the time hasn't changed. assert ts == ts.tz_convert(dateutil.tz.tzutc()) # from system utc to real utc ts = Timestamp('2001-01-05 11:56', tz=maybe_get_tz('dateutil/UTC')) # check that the time hasn't changed. assert ts == ts.tz_convert(dateutil.tz.tzutc())
def tz(self, tz): """ Construct a dateutil timezone. Use tslib.maybe_get_tz so that we get the filename on the tz right on windows. See #7337. """ return timezones.maybe_get_tz('dateutil/' + tz)
def __init__(self, unit="ns", tz=None): if isinstance(unit, DatetimeTZDtype): unit, tz = unit.unit, unit.tz if unit != 'ns': if isinstance(unit, str) and tz is None: # maybe a string like datetime64[ns, tz], which we support for # now. result = type(self).construct_from_string(unit) unit = result.unit tz = result.tz msg = ( "Passing a dtype alias like 'datetime64[ns, {tz}]' " "to DatetimeTZDtype is deprecated. Use " "'DatetimeTZDtype.construct_from_string()' instead." ) warnings.warn(msg.format(tz=tz), FutureWarning, stacklevel=2) else: raise ValueError("DatetimeTZDtype only supports ns units") if tz: tz = timezones.maybe_get_tz(tz) tz = timezones.tz_standardize(tz) elif tz is not None: raise pytz.UnknownTimeZoneError(tz) elif tz is None: raise TypeError("A 'tz' is required.") self._unit = unit self._tz = tz
def test_dti_tz_convert_utc_to_local_no_modify(self, tz): rng = date_range('3/11/2012', '3/12/2012', freq='H', tz='utc') rng_eastern = rng.tz_convert(tz) # Values are unmodified tm.assert_numpy_array_equal(rng.asi8, rng_eastern.asi8) assert timezones.tz_compare(rng_eastern.tz, timezones.maybe_get_tz(tz))
def test_tslib_tz_convert(self): def compare_utc_to_local(tz_didx, utc_didx): f = lambda x: conversion.tz_convert_single(x, 'UTC', tz_didx.tz) result = conversion.tz_convert(tz_didx.asi8, 'UTC', tz_didx.tz) result_single = np.vectorize(f)(tz_didx.asi8) tm.assert_numpy_array_equal(result, result_single) def compare_local_to_utc(tz_didx, utc_didx): f = lambda x: conversion.tz_convert_single(x, tz_didx.tz, 'UTC') result = conversion.tz_convert(utc_didx.asi8, tz_didx.tz, 'UTC') result_single = np.vectorize(f)(utc_didx.asi8) tm.assert_numpy_array_equal(result, result_single) for tz in ['UTC', 'Asia/Tokyo', 'US/Eastern', 'Europe/Moscow']: # US: 2014-03-09 - 2014-11-11 # MOSCOW: 2014-10-26 / 2014-12-31 tz_didx = date_range('2014-03-01', '2015-01-10', freq='H', tz=tz) utc_didx = date_range('2014-03-01', '2015-01-10', freq='H') compare_utc_to_local(tz_didx, utc_didx) # local tz to UTC can be differ in hourly (or higher) freqs because # of DST compare_local_to_utc(tz_didx, utc_didx) tz_didx = date_range('2000-01-01', '2020-01-01', freq='D', tz=tz) utc_didx = date_range('2000-01-01', '2020-01-01', freq='D') compare_utc_to_local(tz_didx, utc_didx) compare_local_to_utc(tz_didx, utc_didx) tz_didx = date_range('2000-01-01', '2100-01-01', freq='A', tz=tz) utc_didx = date_range('2000-01-01', '2100-01-01', freq='A') compare_utc_to_local(tz_didx, utc_didx) compare_local_to_utc(tz_didx, utc_didx) # Check empty array result = conversion.tz_convert(np.array([], dtype=np.int64), timezones.maybe_get_tz('US/Eastern'), timezones.maybe_get_tz('Asia/Tokyo')) tm.assert_numpy_array_equal(result, np.array([], dtype=np.int64)) # Check all-NaT array result = conversion.tz_convert(np.array([tslib.iNaT], dtype=np.int64), timezones.maybe_get_tz('US/Eastern'), timezones.maybe_get_tz('Asia/Tokyo')) tm.assert_numpy_array_equal(result, np.array( [tslib.iNaT], dtype=np.int64))
def test_series_tz_localize_empty(self, tzstr): # GH#2248 ser = Series() ser2 = ser.tz_localize('utc') assert ser2.index.tz == pytz.utc ser2 = ser.tz_localize(tzstr) timezones.tz_compare(ser2.index.tz, timezones.maybe_get_tz(tzstr))
def test_timestamp_tz_arg_dateutil(self): from pandas._libs.tslibs.timezones import dateutil_gettz from pandas._libs.tslibs.timezones import maybe_get_tz for case in ['dateutil/Europe/Brussels', 'dateutil/Asia/Tokyo', 'dateutil/US/Pacific']: p = Period('1/1/2005', freq='M').to_timestamp( tz=maybe_get_tz(case)) exp = Timestamp('1/1/2005', tz='UTC').tz_convert(case) assert p == exp assert p.tz == dateutil_gettz(case.split('/', 1)[1]) assert p.tz == exp.tz p = Period('1/1/2005', freq='M').to_timestamp(freq='3H', tz=maybe_get_tz(case)) exp = Timestamp('1/1/2005', tz='UTC').tz_convert(case) assert p == exp assert p.tz == dateutil_gettz(case.split('/', 1)[1]) assert p.tz == exp.tz
def test_timetz_accessor(self, tz_naive_fixture): # GH21358 tz = timezones.maybe_get_tz(tz_naive_fixture) expected = np.array([time(10, 20, 30, tzinfo=tz), pd.NaT]) index = DatetimeIndex(['2018-06-04 10:20:30', pd.NaT], tz=tz) result = index.timetz tm.assert_numpy_array_equal(result, expected)
def __init__(self, unit="ns", tz=None): """ An ExtensionDtype for timezone-aware datetime data. Parameters ---------- unit : str, default "ns" The precision of the datetime data. Currently limited to ``"ns"``. tz : str, int, or datetime.tzinfo The timezone. Raises ------ pytz.UnknownTimeZoneError When the requested timezone cannot be found. Examples -------- >>> pd.core.dtypes.dtypes.DatetimeTZDtype(tz='UTC') datetime64[ns, UTC] >>> pd.core.dtypes.dtypes.DatetimeTZDtype(tz='dateutil/US/Central') datetime64[ns, tzfile('/usr/share/zoneinfo/US/Central')] """ if isinstance(unit, DatetimeTZDtype): unit, tz = unit.unit, unit.tz if unit != 'ns': if isinstance(unit, compat.string_types) and tz is None: # maybe a string like datetime64[ns, tz], which we support for # now. result = type(self).construct_from_string(unit) unit = result.unit tz = result.tz msg = ( "Passing a dtype alias like 'datetime64[ns, {tz}]' " "to DatetimeTZDtype is deprecated. Use " "'DatetimeTZDtype.construct_from_string()' instead." ) warnings.warn(msg.format(tz=tz), FutureWarning, stacklevel=2) else: raise ValueError("DatetimeTZDtype only supports ns units") if tz: tz = timezones.maybe_get_tz(tz) tz = timezones.tz_standardize(tz) elif tz is not None: raise pytz.UnknownTimeZoneError(tz) elif tz is None: raise TypeError("A 'tz' is required.") self._unit = unit self._tz = tz
def test_dt_timetz_accessor(self, tz_naive_fixture): # GH21358 tz = maybe_get_tz(tz_naive_fixture) dtindex = pd.DatetimeIndex(['2014-04-04 23:56', '2014-07-18 21:24', '2015-11-22 22:14'], tz=tz) s = Series(dtindex) expected = Series([time(23, 56, tzinfo=tz), time(21, 24, tzinfo=tz), time(22, 14, tzinfo=tz)]) result = s.dt.timetz tm.assert_series_equal(result, expected)
def test_getitem_pydatetime_tz(self, tzstr): tz = timezones.maybe_get_tz(tzstr) index = date_range(start='2012-12-24 16:00', end='2012-12-24 18:00', freq='H', tz=tzstr) ts = Series(index=index, data=index.hour) time_pandas = Timestamp('2012-12-24 17:00', tz=tzstr) dt = datetime(2012, 12, 24, 17, 0) time_datetime = conversion.localize_pydatetime(dt, tz) assert ts[time_pandas] == ts[time_datetime]
def test_tzlocal(self): # GH 13583 ts = Timestamp('2011-01-01', tz=dateutil.tz.tzlocal()) assert ts.tz == dateutil.tz.tzlocal() assert "tz='tzlocal()')" in repr(ts) tz = timezones.maybe_get_tz('tzlocal()') assert tz == dateutil.tz.tzlocal() # get offset using normal datetime for test offset = dateutil.tz.tzlocal().utcoffset(datetime(2011, 1, 1)) offset = offset.total_seconds() * 1000000000 assert ts.value + offset == Timestamp('2011-01-01').value
def test_timestamp_timetz_equivalent_with_datetime_tz(self, tz_naive_fixture): # GH21358 tz = timezones.maybe_get_tz(tz_naive_fixture) stamp = Timestamp('2018-06-04 10:20:30', tz=tz) _datetime = datetime(2018, 6, 4, hour=10, minute=20, second=30, tzinfo=tz) result = stamp.timetz() expected = _datetime.timetz() assert result == expected
def _infer_tz_from_endpoints(start, end, tz): """ If a timezone is not explicitly given via `tz`, see if one can be inferred from the `start` and `end` endpoints. If more than one of these inputs provides a timezone, require that they all agree. Parameters ---------- start : Timestamp end : Timestamp tz : tzinfo or None Returns ------- tz : tzinfo or None inferred_tz : tzinfo or None Raises ------ TypeError : if start and end timezones do not agree """ try: inferred_tz = timezones.infer_tzinfo(start, end) except Exception: raise TypeError('Start and end cannot both be tz-aware with ' 'different timezones') inferred_tz = timezones.maybe_get_tz(inferred_tz) tz = timezones.maybe_get_tz(tz) if tz is not None and inferred_tz is not None: if not timezones.tz_compare(inferred_tz, tz): raise AssertionError("Inferred time zone not equal to passed " "time zone") elif inferred_tz is not None: tz = inferred_tz return tz, inferred_tz
def test_timestamp_timetz_equivalent_with_datetime_tz( self, tz_naive_fixture): # GH21358 tz = timezones.maybe_get_tz(tz_naive_fixture) stamp = Timestamp("2018-06-04 10:20:30", tz=tz) _datetime = datetime(2018, 6, 4, hour=10, minute=20, second=30, tzinfo=tz) result = stamp.timetz() expected = _datetime.timetz() assert result == expected
def test_localized_at_time_between_time(self, tzstr): from datetime import time tz = timezones.maybe_get_tz(tzstr) rng = date_range('4/16/2012', '5/1/2012', freq='H') ts = Series(np.random.randn(len(rng)), index=rng) ts_local = ts.tz_localize(tzstr) result = ts_local.at_time(time(10, 0)) expected = ts.at_time(time(10, 0)).tz_localize(tzstr) tm.assert_series_equal(result, expected) assert timezones.tz_compare(result.index.tz, tz) t1, t2 = time(10, 0), time(11, 0) result = ts_local.between_time(t1, t2) expected = ts.between_time(t1, t2).tz_localize(tzstr) tm.assert_series_equal(result, expected) assert timezones.tz_compare(result.index.tz, tz)
def test_utc_box_timestamp_and_localize(self, tzstr): tz = timezones.maybe_get_tz(tzstr) rng = date_range("3/11/2012", "3/12/2012", freq="H", tz="utc") rng_eastern = rng.tz_convert(tzstr) expected = rng[-1].astimezone(tz) stamp = rng_eastern[-1] assert stamp == expected assert stamp.tzinfo == expected.tzinfo # right tzinfo rng = date_range("3/13/2012", "3/14/2012", freq="H", tz="utc") rng_eastern = rng.tz_convert(tzstr) # test not valid for dateutil timezones. # assert 'EDT' in repr(rng_eastern[0].tzinfo) assert "EDT" in repr(rng_eastern[0].tzinfo) or "tzfile" in repr( rng_eastern[0].tzinfo)
def test_localized_at_time_between_time(self, tzstr): from datetime import time tz = timezones.maybe_get_tz(tzstr) rng = date_range('4/16/2012', '5/1/2012', freq='H') ts = Series(np.random.randn(len(rng)), index=rng) ts_local = ts.tz_localize(tzstr) result = ts_local.at_time(time(10, 0)) expected = ts.at_time(time(10, 0)).tz_localize(tzstr) tm.assert_series_equal(result, expected) assert timezones.tz_compare(result.index.tz, tz) t1, t2 = time(10, 0), time(11, 0) result = ts_local.between_time(t1, t2) expected = ts.between_time(t1, t2).tz_localize(tzstr) tm.assert_series_equal(result, expected) assert timezones.tz_compare(result.index.tz, tz)
def test_utc_box_timestamp_and_localize(self, tzstr): tz = timezones.maybe_get_tz(tzstr) rng = date_range('3/11/2012', '3/12/2012', freq='H', tz='utc') rng_eastern = rng.tz_convert(tzstr) expected = rng[-1].astimezone(tz) stamp = rng_eastern[-1] assert stamp == expected assert stamp.tzinfo == expected.tzinfo # right tzinfo rng = date_range('3/13/2012', '3/14/2012', freq='H', tz='utc') rng_eastern = rng.tz_convert(tzstr) # test not valid for dateutil timezones. # assert 'EDT' in repr(rng_eastern[0].tzinfo) assert ('EDT' in repr(rng_eastern[0].tzinfo) or 'tzfile' in repr(rng_eastern[0].tzinfo))
def _simple_new(cls, values, freq=None, tz=None, **kwargs): """ we require the we have a dtype compat for the values if we are passed a non-dtype compat, then coerce using the constructor """ if getattr(values, 'dtype', None) is None: # empty, but with dtype compat if values is None: values = np.empty(0, dtype=_NS_DTYPE) return cls(values, freq=freq, tz=tz, **kwargs) values = np.array(values, copy=False) if not is_datetime64_dtype(values): values = ensure_int64(values).view(_NS_DTYPE) result = object.__new__(cls) result._data = values result._freq = freq tz = timezones.maybe_get_tz(tz) result._tz = timezones.tz_standardize(tz) return result
def _simple_new(cls, values, freq=None, tz=None, **kwargs): """ we require the we have a dtype compat for the values if we are passed a non-dtype compat, then coerce using the constructor """ if getattr(values, 'dtype', None) is None: # empty, but with dtype compat if values is None: values = np.empty(0, dtype=_NS_DTYPE) return cls(values, freq=freq, tz=tz, **kwargs) values = np.array(values, copy=False) if not is_datetime64_dtype(values): values = _ensure_int64(values).view(_NS_DTYPE) result = object.__new__(cls) result._data = values result._freq = freq tz = timezones.maybe_get_tz(tz) result._tz = timezones.tz_standardize(tz) return result
def test_range_tz_dateutil(self): # see gh-2906 # Use maybe_get_tz to fix filename in tz under dateutil. from pandas._libs.tslibs.timezones import maybe_get_tz tz = lambda x: maybe_get_tz('dateutil/' + x) start = datetime(2011, 1, 1, tzinfo=tz('US/Eastern')) end = datetime(2011, 1, 3, tzinfo=tz('US/Eastern')) dr = date_range(start=start, periods=3) assert dr.tz == tz('US/Eastern') assert dr[0] == start assert dr[2] == end dr = date_range(end=end, periods=3) assert dr.tz == tz('US/Eastern') assert dr[0] == start assert dr[2] == end dr = date_range(start=start, end=end) assert dr.tz == tz('US/Eastern') assert dr[0] == start assert dr[2] == end
def test_range_tz_dateutil(self): # see gh-2906 # Use maybe_get_tz to fix filename in tz under dateutil. from pandas._libs.tslibs.timezones import maybe_get_tz tz = lambda x: maybe_get_tz('dateutil/' + x) start = datetime(2011, 1, 1, tzinfo=tz('US/Eastern')) end = datetime(2011, 1, 3, tzinfo=tz('US/Eastern')) dr = date_range(start=start, periods=3) assert dr.tz == tz('US/Eastern') assert dr[0] == start assert dr[2] == end dr = date_range(end=end, periods=3) assert dr.tz == tz('US/Eastern') assert dr[0] == start assert dr[2] == end dr = date_range(start=start, end=end) assert dr.tz == tz('US/Eastern') assert dr[0] == start assert dr[2] == end
def test_tz_compare_utc(utc_fixture, utc_fixture2): tz = timezones.maybe_get_tz(utc_fixture) tz2 = timezones.maybe_get_tz(utc_fixture2) assert timezones.tz_compare(tz, tz2)
def test_tz_convert_corner(self, arr): result = conversion.tz_convert(arr, timezones.maybe_get_tz('US/Eastern'), timezones.maybe_get_tz('Asia/Tokyo')) tm.assert_numpy_array_equal(result, arr)
def test_tzlocal_maybe_get_tz(): # see gh-13583 tz = timezones.maybe_get_tz("tzlocal()") assert tz == dateutil.tz.tzlocal()
def tz_localize(self, tz, ambiguous='raise', errors='raise'): """ Localize tz-naive Datetime Array/Index to tz-aware Datetime Array/Index. This method takes a time zone (tz) naive Datetime Array/Index object and makes this time zone aware. It does not move the time to another time zone. Time zone localization helps to switch from time zone aware to time zone unaware objects. Parameters ---------- tz : string, pytz.timezone, dateutil.tz.tzfile or None Time zone to convert timestamps to. Passing ``None`` will remove the time zone information preserving local time. ambiguous : str {'infer', 'NaT', 'raise'} or bool array, default 'raise' - 'infer' will attempt to infer fall dst-transition hours based on order - bool-ndarray where True signifies a DST time, False signifies a non-DST time (note that this flag is only applicable for ambiguous times) - 'NaT' will return NaT where there are ambiguous times - 'raise' will raise an AmbiguousTimeError if there are ambiguous times errors : {'raise', 'coerce'}, default 'raise' - 'raise' will raise a NonExistentTimeError if a timestamp is not valid in the specified time zone (e.g. due to a transition from or to DST time) - 'coerce' will return NaT if the timestamp can not be converted to the specified time zone .. versionadded:: 0.19.0 Returns ------- result : same type as self Array/Index converted to the specified time zone. Raises ------ TypeError If the Datetime Array/Index is tz-aware and tz is not None. See Also -------- DatetimeIndex.tz_convert : Convert tz-aware DatetimeIndex from one time zone to another. Examples -------- >>> tz_naive = pd.date_range('2018-03-01 09:00', periods=3) >>> tz_naive DatetimeIndex(['2018-03-01 09:00:00', '2018-03-02 09:00:00', '2018-03-03 09:00:00'], dtype='datetime64[ns]', freq='D') Localize DatetimeIndex in US/Eastern time zone: >>> tz_aware = tz_naive.tz_localize(tz='US/Eastern') >>> tz_aware DatetimeIndex(['2018-03-01 09:00:00-05:00', '2018-03-02 09:00:00-05:00', '2018-03-03 09:00:00-05:00'], dtype='datetime64[ns, US/Eastern]', freq='D') With the ``tz=None``, we can remove the time zone information while keeping the local time (not converted to UTC): >>> tz_aware.tz_localize(None) DatetimeIndex(['2018-03-01 09:00:00', '2018-03-02 09:00:00', '2018-03-03 09:00:00'], dtype='datetime64[ns]', freq='D') """ if self.tz is not None: if tz is None: new_dates = conversion.tz_convert(self.asi8, 'UTC', self.tz) else: raise TypeError("Already tz-aware, use tz_convert to convert.") else: tz = timezones.maybe_get_tz(tz) # Convert to UTC new_dates = conversion.tz_localize_to_utc(self.asi8, tz, ambiguous=ambiguous, errors=errors) new_dates = new_dates.view(_NS_DTYPE) return self._shallow_copy(new_dates, tz=tz)
def _convert_listlike_datetimes( arg, format: str | None, name: Hashable = None, tz: Timezone | None = None, unit: str | None = None, errors: str = "raise", infer_datetime_format: bool = False, dayfirst: bool | None = None, yearfirst: bool | None = None, exact: bool = True, ): """ Helper function for to_datetime. Performs the conversions of 1D listlike of dates Parameters ---------- arg : list, tuple, ndarray, Series, Index date to be parsed name : object None or string for the Index name tz : object None or 'utc' unit : str None or string of the frequency of the passed data errors : str error handing behaviors from to_datetime, 'raise', 'coerce', 'ignore' infer_datetime_format : bool, default False inferring format behavior from to_datetime dayfirst : bool dayfirst parsing behavior from to_datetime yearfirst : bool yearfirst parsing behavior from to_datetime exact : bool, default True exact format matching behavior from to_datetime Returns ------- Index-like of parsed dates """ if isinstance(arg, (list, tuple)): arg = np.array(arg, dtype="O") arg_dtype = getattr(arg, "dtype", None) # these are shortcutable if is_datetime64tz_dtype(arg_dtype): if not isinstance(arg, (DatetimeArray, DatetimeIndex)): return DatetimeIndex(arg, tz=tz, name=name) if tz == "utc": arg = arg.tz_convert(None).tz_localize(tz) return arg elif is_datetime64_ns_dtype(arg_dtype): if not isinstance(arg, (DatetimeArray, DatetimeIndex)): try: return DatetimeIndex(arg, tz=tz, name=name) except ValueError: pass elif tz: # DatetimeArray, DatetimeIndex return arg.tz_localize(tz) return arg elif unit is not None: if format is not None: raise ValueError("cannot specify both format and unit") return _to_datetime_with_unit(arg, unit, name, tz, errors) elif getattr(arg, "ndim", 1) > 1: raise TypeError( "arg must be a string, datetime, list, tuple, 1-d array, or Series" ) # warn if passing timedelta64, raise for PeriodDtype # NB: this must come after unit transformation orig_arg = arg try: arg, _ = maybe_convert_dtype(arg, copy=False, tz=timezones.maybe_get_tz(tz)) except TypeError: if errors == "coerce": npvalues = np.array(["NaT"], dtype="datetime64[ns]").repeat(len(arg)) return DatetimeIndex(npvalues, name=name) elif errors == "ignore": idx = Index(arg, name=name) return idx raise arg = ensure_object(arg) require_iso8601 = False if infer_datetime_format and format is None: format = _guess_datetime_format_for_array(arg, dayfirst=dayfirst) if format is not None: # There is a special fast-path for iso8601 formatted # datetime strings, so in those cases don't use the inferred # format because this path makes process slower in this # special case format_is_iso8601 = format_is_iso(format) if format_is_iso8601: require_iso8601 = not infer_datetime_format format = None if format is not None: res = _to_datetime_with_format(arg, orig_arg, name, tz, format, exact, errors, infer_datetime_format) if res is not None: return res assert format is None or infer_datetime_format utc = tz == "utc" result, tz_parsed = objects_to_datetime64ns( arg, dayfirst=dayfirst, yearfirst=yearfirst, utc=utc, errors=errors, require_iso8601=require_iso8601, allow_object=True, ) if tz_parsed is not None: # We can take a shortcut since the datetime64 numpy array # is in UTC dta = DatetimeArray(result, dtype=tz_to_dtype(tz_parsed)) return DatetimeIndex._simple_new(dta, name=name) utc = tz == "utc" return _box_as_indexlike(result, utc=utc, name=name)
def test_tz_convert_corner(arr): result = conversion.tz_convert(arr, timezones.maybe_get_tz("US/Eastern"), timezones.maybe_get_tz("Asia/Tokyo")) tm.assert_numpy_array_equal(result, arr)
def tz_localize(self, tz, ambiguous='raise', errors='raise'): """ Localize tz-naive Datetime Array/Index to tz-aware Datetime Array/Index. This method takes a time zone (tz) naive Datetime Array/Index object and makes this time zone aware. It does not move the time to another time zone. Time zone localization helps to switch from time zone aware to time zone unaware objects. Parameters ---------- tz : string, pytz.timezone, dateutil.tz.tzfile or None Time zone to convert timestamps to. Passing ``None`` will remove the time zone information preserving local time. ambiguous : str {'infer', 'NaT', 'raise'} or bool array, default 'raise' - 'infer' will attempt to infer fall dst-transition hours based on order - bool-ndarray where True signifies a DST time, False signifies a non-DST time (note that this flag is only applicable for ambiguous times) - 'NaT' will return NaT where there are ambiguous times - 'raise' will raise an AmbiguousTimeError if there are ambiguous times errors : {'raise', 'coerce'}, default 'raise' - 'raise' will raise a NonExistentTimeError if a timestamp is not valid in the specified time zone (e.g. due to a transition from or to DST time) - 'coerce' will return NaT if the timestamp can not be converted to the specified time zone .. versionadded:: 0.19.0 Returns ------- result : same type as self Array/Index converted to the specified time zone. Raises ------ TypeError If the Datetime Array/Index is tz-aware and tz is not None. See Also -------- DatetimeIndex.tz_convert : Convert tz-aware DatetimeIndex from one time zone to another. Examples -------- >>> tz_naive = pd.date_range('2018-03-01 09:00', periods=3) >>> tz_naive DatetimeIndex(['2018-03-01 09:00:00', '2018-03-02 09:00:00', '2018-03-03 09:00:00'], dtype='datetime64[ns]', freq='D') Localize DatetimeIndex in US/Eastern time zone: >>> tz_aware = tz_naive.tz_localize(tz='US/Eastern') >>> tz_aware DatetimeIndex(['2018-03-01 09:00:00-05:00', '2018-03-02 09:00:00-05:00', '2018-03-03 09:00:00-05:00'], dtype='datetime64[ns, US/Eastern]', freq='D') With the ``tz=None``, we can remove the time zone information while keeping the local time (not converted to UTC): >>> tz_aware.tz_localize(None) DatetimeIndex(['2018-03-01 09:00:00', '2018-03-02 09:00:00', '2018-03-03 09:00:00'], dtype='datetime64[ns]', freq='D') """ if self.tz is not None: if tz is None: new_dates = conversion.tz_convert(self.asi8, 'UTC', self.tz) else: raise TypeError("Already tz-aware, use tz_convert to convert.") else: tz = timezones.maybe_get_tz(tz) # Convert to UTC new_dates = conversion.tz_localize_to_utc(self.asi8, tz, ambiguous=ambiguous, errors=errors) new_dates = new_dates.view(_NS_DTYPE) return self._shallow_copy(new_dates, tz=tz)
def test_append_with_timezones_dateutil(setup_path): from datetime import timedelta # use maybe_get_tz instead of dateutil.tz.gettz to handle the windows # filename issues. from pandas._libs.tslibs.timezones import maybe_get_tz gettz = lambda x: maybe_get_tz("dateutil/" + x) # as columns with ensure_clean_store(setup_path) as store: _maybe_remove(store, "df_tz") df = DataFrame( dict(A=[ Timestamp("20130102 2:00:00", tz=gettz("US/Eastern")) + timedelta(hours=1) * i for i in range(5) ])) store.append("df_tz", df, data_columns=["A"]) result = store["df_tz"] _compare_with_tz(result, df) tm.assert_frame_equal(result, df) # select with tz aware expected = df[df.A >= df.A[3]] result = store.select("df_tz", where="A>=df.A[3]") _compare_with_tz(result, expected) # ensure we include dates in DST and STD time here. _maybe_remove(store, "df_tz") df = DataFrame( dict( A=Timestamp("20130102", tz=gettz("US/Eastern")), B=Timestamp("20130603", tz=gettz("US/Eastern")), ), index=range(5), ) store.append("df_tz", df) result = store["df_tz"] _compare_with_tz(result, df) tm.assert_frame_equal(result, df) df = DataFrame( dict( A=Timestamp("20130102", tz=gettz("US/Eastern")), B=Timestamp("20130102", tz=gettz("EET")), ), index=range(5), ) with pytest.raises(ValueError): store.append("df_tz", df) # this is ok _maybe_remove(store, "df_tz") store.append("df_tz", df, data_columns=["A", "B"]) result = store["df_tz"] _compare_with_tz(result, df) tm.assert_frame_equal(result, df) # can't append with diff timezone df = DataFrame( dict( A=Timestamp("20130102", tz=gettz("US/Eastern")), B=Timestamp("20130102", tz=gettz("CET")), ), index=range(5), ) with pytest.raises(ValueError): store.append("df_tz", df) # as index with ensure_clean_store(setup_path) as store: # GH 4098 example df = DataFrame( dict(A=Series( range(3), index=date_range( "2000-1-1", periods=3, freq="H", tz=gettz("US/Eastern")), ))) _maybe_remove(store, "df") store.put("df", df) result = store.select("df") tm.assert_frame_equal(result, df) _maybe_remove(store, "df") store.append("df", df) result = store.select("df") tm.assert_frame_equal(result, df)
def test_tz_convert_corner(arr): result = tzconversion.tz_convert_from_utc( arr, timezones.maybe_get_tz("Asia/Tokyo")) tm.assert_numpy_array_equal(result, arr)
def test_append_with_timezones_dateutil(setup_path): from datetime import timedelta # use maybe_get_tz instead of dateutil.tz.gettz to handle the windows # filename issues. from pandas._libs.tslibs.timezones import maybe_get_tz gettz = lambda x: maybe_get_tz("dateutil/" + x) # as columns with ensure_clean_store(setup_path) as store: _maybe_remove(store, "df_tz") df = DataFrame( { "A": [ Timestamp("20130102 2:00:00", tz=gettz("US/Eastern")) + timedelta(hours=1) * i for i in range(5) ] } ) store.append("df_tz", df, data_columns=["A"]) result = store["df_tz"] _compare_with_tz(result, df) tm.assert_frame_equal(result, df) # select with tz aware expected = df[df.A >= df.A[3]] result = store.select("df_tz", where="A>=df.A[3]") _compare_with_tz(result, expected) # ensure we include dates in DST and STD time here. _maybe_remove(store, "df_tz") df = DataFrame( { "A": Timestamp("20130102", tz=gettz("US/Eastern")), "B": Timestamp("20130603", tz=gettz("US/Eastern")), }, index=range(5), ) store.append("df_tz", df) result = store["df_tz"] _compare_with_tz(result, df) tm.assert_frame_equal(result, df) df = DataFrame( { "A": Timestamp("20130102", tz=gettz("US/Eastern")), "B": Timestamp("20130102", tz=gettz("EET")), }, index=range(5), ) msg = ( r"invalid info for \[values_block_1\] for \[tz\], " r"existing_value \[dateutil/.*US/Eastern\] " r"conflicts with new value \[dateutil/.*EET\]" ) with pytest.raises(ValueError, match=msg): store.append("df_tz", df) # this is ok _maybe_remove(store, "df_tz") store.append("df_tz", df, data_columns=["A", "B"]) result = store["df_tz"] _compare_with_tz(result, df) tm.assert_frame_equal(result, df) # can't append with diff timezone df = DataFrame( { "A": Timestamp("20130102", tz=gettz("US/Eastern")), "B": Timestamp("20130102", tz=gettz("CET")), }, index=range(5), ) msg = ( r"invalid info for \[B\] for \[tz\], " r"existing_value \[dateutil/.*EET\] " r"conflicts with new value \[dateutil/.*CET\]" ) with pytest.raises(ValueError, match=msg): store.append("df_tz", df) # as index with ensure_clean_store(setup_path) as store: dti = date_range("2000-1-1", periods=3, freq="H", tz=gettz("US/Eastern")) dti = dti._with_freq(None) # freq doesnt round-trip # GH 4098 example df = DataFrame({"A": Series(range(3), index=dti)}) _maybe_remove(store, "df") store.put("df", df) result = store.select("df") tm.assert_frame_equal(result, df) _maybe_remove(store, "df") store.append("df", df) result = store.select("df") tm.assert_frame_equal(result, df)
def test_tzlocal_maybe_get_tz(): # see gh-13583 tz = timezones.maybe_get_tz('tzlocal()') assert tz == dateutil.tz.tzlocal()
def test_date_range_timezone_str_argument(self, tzstr): tz = timezones.maybe_get_tz(tzstr) result = date_range('1/1/2000', periods=10, tz=tzstr) expected = date_range('1/1/2000', periods=10, tz=tz) tm.assert_index_equal(result, expected)
def test_tz_convert_corner(arr): result = conversion.tz_convert(arr, timezones.maybe_get_tz("US/Eastern"), timezones.maybe_get_tz("Asia/Tokyo")) tm.assert_numpy_array_equal(result, arr)
def _compare_with_tz(a, b): tm.assert_frame_equal(a, b) # compare the zones on each element for c in a.columns: for i in a.index: a_e = a.loc[i, c] b_e = b.loc[i, c] if not (a_e == b_e and a_e.tz == b_e.tz): raise AssertionError(f"invalid tz comparison [{a_e}] [{b_e}]") # use maybe_get_tz instead of dateutil.tz.gettz to handle the windows # filename issues. gettz_dateutil = lambda x: maybe_get_tz("dateutil/" + x) gettz_pytz = lambda x: x @pytest.mark.parametrize("gettz", [gettz_dateutil, gettz_pytz]) def test_append_with_timezones(setup_path, gettz): # as columns # Single-tzinfo, no DST transition df_est = DataFrame( { "A": [ Timestamp("20130102 2:00:00", tz=gettz("US/Eastern")) + timedelta(hours=1) * i for i in range(5) ]
def tz_convert(self, tz): """ Convert tz-aware Datetime Array/Index from one time zone to another. Parameters ---------- tz : string, pytz.timezone, dateutil.tz.tzfile or None Time zone for time. Corresponding timestamps would be converted to this time zone of the Datetime Array/Index. A `tz` of None will convert to UTC and remove the timezone information. Returns ------- normalized : same type as self Raises ------ TypeError If Datetime Array/Index is tz-naive. See Also -------- DatetimeIndex.tz : A timezone that has a variable offset from UTC DatetimeIndex.tz_localize : Localize tz-naive DatetimeIndex to a given time zone, or remove timezone from a tz-aware DatetimeIndex. Examples -------- With the `tz` parameter, we can change the DatetimeIndex to other time zones: >>> dti = pd.DatetimeIndex(start='2014-08-01 09:00', ... freq='H', periods=3, tz='Europe/Berlin') >>> dti DatetimeIndex(['2014-08-01 09:00:00+02:00', '2014-08-01 10:00:00+02:00', '2014-08-01 11:00:00+02:00'], dtype='datetime64[ns, Europe/Berlin]', freq='H') >>> dti.tz_convert('US/Central') DatetimeIndex(['2014-08-01 02:00:00-05:00', '2014-08-01 03:00:00-05:00', '2014-08-01 04:00:00-05:00'], dtype='datetime64[ns, US/Central]', freq='H') With the ``tz=None``, we can remove the timezone (after converting to UTC if necessary): >>> dti = pd.DatetimeIndex(start='2014-08-01 09:00',freq='H', ... periods=3, tz='Europe/Berlin') >>> dti DatetimeIndex(['2014-08-01 09:00:00+02:00', '2014-08-01 10:00:00+02:00', '2014-08-01 11:00:00+02:00'], dtype='datetime64[ns, Europe/Berlin]', freq='H') >>> dti.tz_convert(None) DatetimeIndex(['2014-08-01 07:00:00', '2014-08-01 08:00:00', '2014-08-01 09:00:00'], dtype='datetime64[ns]', freq='H') """ tz = timezones.maybe_get_tz(tz) if self.tz is None: # tz naive, use tz_localize raise TypeError('Cannot convert tz-naive timestamps, use ' 'tz_localize to localize') # No conversion since timestamps are all UTC to begin with return self._shallow_copy(tz=tz)
def ts_tz(self, ts, tz_aware_fixture): tz = maybe_get_tz(tz_aware_fixture) return Timestamp._from_value_and_reso(ts.value, ts._reso, tz)
def test_is_utc(utc_fixture): tz = timezones.maybe_get_tz(utc_fixture) assert timezones.is_utc(tz)
def tz_convert(self, tz): """ Convert tz-aware Datetime Array/Index from one time zone to another. Parameters ---------- tz : string, pytz.timezone, dateutil.tz.tzfile or None Time zone for time. Corresponding timestamps would be converted to this time zone of the Datetime Array/Index. A `tz` of None will convert to UTC and remove the timezone information. Returns ------- normalized : same type as self Raises ------ TypeError If Datetime Array/Index is tz-naive. See Also -------- DatetimeIndex.tz : A timezone that has a variable offset from UTC DatetimeIndex.tz_localize : Localize tz-naive DatetimeIndex to a given time zone, or remove timezone from a tz-aware DatetimeIndex. Examples -------- With the `tz` parameter, we can change the DatetimeIndex to other time zones: >>> dti = pd.DatetimeIndex(start='2014-08-01 09:00', ... freq='H', periods=3, tz='Europe/Berlin') >>> dti DatetimeIndex(['2014-08-01 09:00:00+02:00', '2014-08-01 10:00:00+02:00', '2014-08-01 11:00:00+02:00'], dtype='datetime64[ns, Europe/Berlin]', freq='H') >>> dti.tz_convert('US/Central') DatetimeIndex(['2014-08-01 02:00:00-05:00', '2014-08-01 03:00:00-05:00', '2014-08-01 04:00:00-05:00'], dtype='datetime64[ns, US/Central]', freq='H') With the ``tz=None``, we can remove the timezone (after converting to UTC if necessary): >>> dti = pd.DatetimeIndex(start='2014-08-01 09:00',freq='H', ... periods=3, tz='Europe/Berlin') >>> dti DatetimeIndex(['2014-08-01 09:00:00+02:00', '2014-08-01 10:00:00+02:00', '2014-08-01 11:00:00+02:00'], dtype='datetime64[ns, Europe/Berlin]', freq='H') >>> dti.tz_convert(None) DatetimeIndex(['2014-08-01 07:00:00', '2014-08-01 08:00:00', '2014-08-01 09:00:00'], dtype='datetime64[ns]', freq='H') """ tz = timezones.maybe_get_tz(tz) if self.tz is None: # tz naive, use tz_localize raise TypeError('Cannot convert tz-naive timestamps, use ' 'tz_localize to localize') # No conversion since timestamps are all UTC to begin with return self._shallow_copy(tz=tz)
def test_tz_convert_corner(self, arr): result = conversion.tz_convert(arr, timezones.maybe_get_tz('US/Eastern'), timezones.maybe_get_tz('Asia/Tokyo')) tm.assert_numpy_array_equal(result, arr)
def _check_offsetfunc_works(self, offset, funcname, dt, expected, normalize=False): if normalize and issubclass(offset, Tick): # normalize=True disallowed for Tick subclasses GH#21427 return offset_s = self._get_offset(offset, normalize=normalize) func = getattr(offset_s, funcname) result = func(dt) assert isinstance(result, Timestamp) assert result == expected result = func(Timestamp(dt)) assert isinstance(result, Timestamp) assert result == expected # see gh-14101 exp_warning = None ts = Timestamp(dt) + Nano(5) if (type(offset_s).__name__ == "DateOffset" and (funcname in ["apply", "_apply"] or normalize) and ts.nanosecond > 0): exp_warning = UserWarning # test nanosecond is preserved with tm.assert_produces_warning(exp_warning): result = func(ts) if exp_warning is None and funcname == "_apply": # GH#44522 # Check in this particular case to avoid headaches with # testing for multiple warnings produced by the same call. with tm.assert_produces_warning(FutureWarning, match="apply is deprecated"): res2 = offset_s.apply(ts) assert type(res2) is type(result) assert res2 == result assert isinstance(result, Timestamp) if normalize is False: assert result == expected + Nano(5) else: assert result == expected if isinstance(dt, np.datetime64): # test tz when input is datetime or Timestamp return for tz in self.timezones: expected_localize = expected.tz_localize(tz) tz_obj = timezones.maybe_get_tz(tz) dt_tz = conversion.localize_pydatetime(dt, tz_obj) result = func(dt_tz) assert isinstance(result, Timestamp) assert result == expected_localize result = func(Timestamp(dt, tz=tz)) assert isinstance(result, Timestamp) assert result == expected_localize # see gh-14101 exp_warning = None ts = Timestamp(dt, tz=tz) + Nano(5) if (type(offset_s).__name__ == "DateOffset" and (funcname in ["apply", "_apply"] or normalize) and ts.nanosecond > 0): exp_warning = UserWarning # test nanosecond is preserved with tm.assert_produces_warning(exp_warning): result = func(ts) assert isinstance(result, Timestamp) if normalize is False: assert result == expected_localize + Nano(5) else: assert result == expected_localize
def _check_offsetfunc_works(self, offset, funcname, dt, expected, normalize=False): if normalize and issubclass(offset, Tick): # normalize=True disallowed for Tick subclasses GH#21427 return offset_s = self._get_offset(offset, normalize=normalize) func = getattr(offset_s, funcname) result = func(dt) assert isinstance(result, Timestamp) assert result == expected result = func(Timestamp(dt)) assert isinstance(result, Timestamp) assert result == expected # see gh-14101 exp_warning = None ts = Timestamp(dt) + Nano(5) if (type(offset_s).__name__ == "DateOffset" and (funcname == "apply" or normalize) and ts.nanosecond > 0): exp_warning = UserWarning # test nanosecond is preserved with tm.assert_produces_warning(exp_warning): result = func(ts) assert isinstance(result, Timestamp) if normalize is False: assert result == expected + Nano(5) else: assert result == expected if isinstance(dt, np.datetime64): # test tz when input is datetime or Timestamp return for tz in self.timezones: expected_localize = expected.tz_localize(tz) tz_obj = timezones.maybe_get_tz(tz) dt_tz = conversion.localize_pydatetime(dt, tz_obj) result = func(dt_tz) assert isinstance(result, Timestamp) assert result == expected_localize result = func(Timestamp(dt, tz=tz)) assert isinstance(result, Timestamp) assert result == expected_localize # see gh-14101 exp_warning = None ts = Timestamp(dt, tz=tz) + Nano(5) if (type(offset_s).__name__ == "DateOffset" and (funcname == "apply" or normalize) and ts.nanosecond > 0): exp_warning = UserWarning # test nanosecond is preserved with tm.assert_produces_warning(exp_warning): result = func(ts) assert isinstance(result, Timestamp) if normalize is False: assert result == expected_localize + Nano(5) else: assert result == expected_localize
def test_date_range_timezone_str_argument(self, tzstr): tz = timezones.maybe_get_tz(tzstr) result = date_range("1/1/2000", periods=10, tz=tzstr) expected = date_range("1/1/2000", periods=10, tz=tz) tm.assert_index_equal(result, expected)