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 validate_tz_from_dtype(dtype, tz): """ If the given dtype is a DatetimeTZDtype, extract the implied tzinfo object from it and check that it does not conflict with the given tz. Parameters ---------- dtype : dtype, str tz : None, tzinfo Returns ------- tz : consensus tzinfo Raises ------ ValueError : on tzinfo mismatch """ if dtype is not None: try: dtype = DatetimeTZDtype.construct_from_string(dtype) dtz = getattr(dtype, 'tz', None) if dtz is not None: if tz is not None and not timezones.tz_compare(tz, dtz): raise ValueError("cannot supply both a tz and a dtype" " with a tz") tz = dtz except TypeError: pass return 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_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_tz_convert(self, ts): ts = Timestamp._from_value_and_reso(ts.value, ts._reso, utc) tz = pytz.timezone("US/Pacific") result = ts.tz_convert(tz) assert isinstance(result, Timestamp) assert result._reso == ts._reso assert tz_compare(result.tz, tz)
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 _maybe_utc_convert(self, other: Index) -> tuple[DatetimeIndex, Index]: this = self if isinstance(other, DatetimeIndex): if (self.tz is None) ^ (other.tz is None): raise TypeError("Cannot join tz-naive with tz-aware DatetimeIndex") if not timezones.tz_compare(self.tz, other.tz): this = self.tz_convert("UTC") other = other.tz_convert("UTC") return this, other
def test_localized_at_time(self, tzstr): 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)
def test_dti_convert_tz_aware_datetime_datetime(self, tz): # GH#1581 dates = [datetime(2000, 1, 1), datetime(2000, 1, 2), datetime(2000, 1, 3)] dates_aware = [conversion.localize_pydatetime(x, tz) for x in dates] result = DatetimeIndex(dates_aware) assert timezones.tz_compare(result.tz, tz) converted = to_datetime(dates_aware, utc=True) ex_vals = np.array([Timestamp(x).value for x in dates_aware]) tm.assert_numpy_array_equal(converted.asi8, ex_vals) assert converted.tz is pytz.utc
def test_dti_convert_tz_aware_datetime_datetime(self, tz): # GH#1581 dates = [datetime(2000, 1, 1), datetime(2000, 1, 2), datetime(2000, 1, 3)] dates_aware = [tslib._localize_pydatetime(x, tz) for x in dates] result = DatetimeIndex(dates_aware) assert timezones.tz_compare(result.tz, tz) converted = to_datetime(dates_aware, utc=True) ex_vals = np.array([Timestamp(x).value for x in dates_aware]) tm.assert_numpy_array_equal(converted.asi8, ex_vals) assert converted.tz is pytz.utc
def test_addsub_offset(self, ts_tz): # specifically non-Tick offset off = offsets.YearBegin(1) result = ts_tz + off assert isinstance(result, Timestamp) assert result._reso == ts_tz._reso # If ts_tz is ever on the last day of the year, the year would be # incremented by one assert result.year == ts_tz.year assert result.day == 31 assert result.month == 12 assert tz_compare(result.tz, ts_tz.tz) result = ts_tz - off assert isinstance(result, Timestamp) assert result._reso == ts_tz._reso assert result.year == ts_tz.year - 1 assert result.day == 31 assert result.month == 12 assert tz_compare(result.tz, ts_tz.tz)
def test_localized_between_time(self, tzstr, frame_or_series): 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) if frame_or_series is DataFrame: ts = ts.to_frame() ts_local = ts.tz_localize(tzstr) 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_equal(result, expected) assert timezones.tz_compare(result.index.tz, tz)
def _maybe_utc_convert(self, other): this = self if not hasattr(self, "tz"): return this, other if isinstance(other, type(self)): if self.tz is not None: if other.tz is None: raise TypeError("Cannot join tz-naive with tz-aware DatetimeIndex") elif other.tz is not None: raise TypeError("Cannot join tz-naive with tz-aware DatetimeIndex") if not timezones.tz_compare(self.tz, other.tz): this = self.tz_convert("UTC") other = other.tz_convert("UTC") return this, other
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 _infer_tz_from_endpoints(start, end, tz): # pragma: no cover """ 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 Raises ------ TypeError : if start and end timezones do not agree """ try: inferred_tz = timezones.infer_tzinfo(start, end) except AssertionError: # infer_tzinfo raises AssertionError if passed mismatched timezones 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
def validate_tz_from_dtype(dtype, tz): """ If the given dtype is a DatetimeTZDtype, extract the implied tzinfo object from it and check that it does not conflict with the given tz. Parameters ---------- dtype : dtype, str tz : None, tzinfo Returns ------- tz : consensus tzinfo Raises ------ ValueError : on tzinfo mismatch """ if dtype is not None: if isinstance(dtype, compat.string_types): try: dtype = DatetimeTZDtype.construct_from_string(dtype) except TypeError: # Things like `datetime64[ns]`, which is OK for the # constructors, but also nonsense, which should be validated # but not by us. We *do* allow non-existent tz errors to # go through pass dtz = getattr(dtype, 'tz', None) if dtz is not None: if tz is not None and not timezones.tz_compare(tz, dtz): raise ValueError("cannot supply both a tz and a dtype" " with a tz") tz = dtz return tz
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 maybe_promote(dtype, fill_value=np.nan): """ Find the minimal dtype that can hold both the given dtype and fill_value. Parameters ---------- dtype : np.dtype or ExtensionDtype fill_value : scalar, default np.nan Returns ------- dtype Upcasted from dtype argument if necessary. fill_value Upcasted from fill_value argument if necessary. """ if not is_scalar(fill_value) and not is_object_dtype(dtype): # with object dtype there is nothing to promote, and the user can # pass pretty much any weird fill_value they like raise ValueError("fill_value must be a scalar") # if we passed an array here, determine the fill value by dtype if isinstance(fill_value, np.ndarray): if issubclass(fill_value.dtype.type, (np.datetime64, np.timedelta64)): fill_value = fill_value.dtype.type("NaT", "ns") else: # we need to change to object type as our # fill_value is of object type if fill_value.dtype == np.object_: dtype = np.dtype(np.object_) fill_value = np.nan if dtype == np.object_ or dtype.kind in ["U", "S"]: # We treat string-like dtypes as object, and _always_ fill # with np.nan fill_value = np.nan dtype = np.dtype(np.object_) # returns tuple of (dtype, fill_value) if issubclass(dtype.type, np.datetime64): if isinstance(fill_value, datetime) and fill_value.tzinfo is not None: # Trying to insert tzaware into tznaive, have to cast to object dtype = np.dtype(np.object_) elif is_integer(fill_value) or (is_float(fill_value) and not isna(fill_value)): dtype = np.dtype(np.object_) else: try: fill_value = tslibs.Timestamp(fill_value).to_datetime64() except (TypeError, ValueError): dtype = np.dtype(np.object_) elif issubclass(dtype.type, np.timedelta64): if ( is_integer(fill_value) or (is_float(fill_value) and not np.isnan(fill_value)) or isinstance(fill_value, str) ): # TODO: What about str that can be a timedelta? dtype = np.dtype(np.object_) else: try: fv = tslibs.Timedelta(fill_value) except ValueError: dtype = np.dtype(np.object_) else: if fv is NaT: # NaT has no `to_timedelta64` method fill_value = np.timedelta64("NaT", "ns") else: fill_value = fv.to_timedelta64() elif is_datetime64tz_dtype(dtype): if isna(fill_value): fill_value = NaT elif not isinstance(fill_value, datetime): dtype = np.dtype(np.object_) elif fill_value.tzinfo is None: dtype = np.dtype(np.object_) elif not tz_compare(fill_value.tzinfo, dtype.tz): # TODO: sure we want to cast here? dtype = np.dtype(np.object_) elif is_extension_array_dtype(dtype) and isna(fill_value): fill_value = dtype.na_value elif is_float(fill_value): if issubclass(dtype.type, np.bool_): dtype = np.dtype(np.object_) elif issubclass(dtype.type, np.integer): dtype = np.dtype(np.float64) elif dtype.kind == "f": mst = np.min_scalar_type(fill_value) if mst > dtype: # e.g. mst is np.float64 and dtype is np.float32 dtype = mst elif dtype.kind == "c": mst = np.min_scalar_type(fill_value) dtype = np.promote_types(dtype, mst) elif is_bool(fill_value): if not issubclass(dtype.type, np.bool_): dtype = np.dtype(np.object_) elif is_integer(fill_value): if issubclass(dtype.type, np.bool_): dtype = np.dtype(np.object_) elif issubclass(dtype.type, np.integer): if not np.can_cast(fill_value, dtype): # upcast to prevent overflow mst = np.min_scalar_type(fill_value) dtype = np.promote_types(dtype, mst) if dtype.kind == "f": # Case where we disagree with numpy dtype = np.dtype(np.object_) elif is_complex(fill_value): if issubclass(dtype.type, np.bool_): dtype = np.dtype(np.object_) elif issubclass(dtype.type, (np.integer, np.floating)): mst = np.min_scalar_type(fill_value) dtype = np.promote_types(dtype, mst) elif dtype.kind == "c": mst = np.min_scalar_type(fill_value) if mst > dtype: # e.g. mst is np.complex128 and dtype is np.complex64 dtype = mst elif fill_value is None: if is_float_dtype(dtype) or is_complex_dtype(dtype): fill_value = np.nan elif is_integer_dtype(dtype): dtype = np.float64 fill_value = np.nan elif is_datetime_or_timedelta_dtype(dtype): fill_value = dtype.type("NaT", "ns") else: dtype = np.dtype(np.object_) fill_value = np.nan else: dtype = np.dtype(np.object_) # in case we have a string that looked like a number if is_extension_array_dtype(dtype): pass elif issubclass(np.dtype(dtype).type, (bytes, str)): dtype = np.dtype(np.object_) fill_value = _ensure_dtype_type(fill_value, dtype) return dtype, fill_value
def test_tzlocal_is_not_utc(): # even if the machine running the test is localized to UTC tz = dateutil.tz.tzlocal() assert not timezones.is_utc(tz) assert not timezones.tz_compare(tz, dateutil.tz.tzutc())
def test_dti_from_tzaware_datetime(self, tz): d = [datetime(2012, 8, 19, tzinfo=tz)] index = DatetimeIndex(d) assert timezones.tz_compare(index.tz, tz)