def test_locale(self): if sys.platform == 'win32': raise nose.SkipTest("skipping on win platforms as locale not available") #GH9744 locales = tm.get_locales() self.assertTrue(len(locales) >= 1)
def setup_class(cls): cls.locales = tm.get_locales() if not cls.locales: pytest.skip("No locales found") tm._skip_if_windows()
def test_locale(self): if sys.platform == 'win32': pytest.skip("skipping on win platforms as locale not available") # GH9744 locales = tm.get_locales() assert len(locales) >= 1
def setUpClass(cls): super(TestLocaleUtils, cls).setUpClass() cls.locales = tm.get_locales() if not cls.locales: raise nose.SkipTest("No locales found") tm._skip_if_windows()
def setUpClass(cls): super(TestLocaleUtils, cls).setUpClass() cls.locales = tm.get_locales() if not cls.locales: pytest.skip("No locales found") tm._skip_if_windows()
def setUpClass(cls): cls.locales = tm.get_locales() if not cls.locales: raise nose.SkipTest("No locales found") if os.name == 'nt': # we're on windows raise nose.SkipTest("Running on Windows")
def test_locale(self): if sys.platform == 'win32': pytest.skip( "skipping on win platforms as locale not available") # GH9744 locales = tm.get_locales() assert len(locales) >= 1
def setup_class(cls): cls.locales = tm.get_locales() cls.current_locale = locale.getlocale() if not cls.locales: pytest.skip("No locales found")
# -*- coding: utf-8 -*- import codecs import locale import os import pytest from pandas._config.localization import can_set_locale, set_locale from pandas.compat import is_platform_windows # TODO: move get_locales into localization, making `tm` import unnecessary. # This is blocked by the need for core.config to be moved to _config. import pandas.util.testing as tm _all_locales = tm.get_locales() or [] _current_locale = locale.getlocale() # Don't run any of these tests if we are on Windows or have no locales. pytestmark = pytest.mark.skipif(is_platform_windows() or not _all_locales, reason="Need non-Windows and locales") _skip_if_only_one_locale = pytest.mark.skipif( len(_all_locales) <= 1, reason="Need multiple locales for meaningful test") def test_can_set_locale_valid_set(): # Can set the default locale. assert can_set_locale("")
def test_get_locales_prefix(self): if len(self.locales) == 1: pytest.skip("Only a single locale found, no point in " "trying to test filtering locale prefixes") first_locale = self.locales[0] assert len(tm.get_locales(prefix=first_locale[:2])) > 0
def test_get_locales(self): # all systems should have at least a single locale assert len(tm.get_locales()) > 0
def test_get_locales_prefix(): first_locale = _all_locales[0] assert len(tm.get_locales(prefix=first_locale[:2])) > 0
def setUpClass(cls): super(TestGoogle, cls).setUpClass() cls.locales = tm.get_locales(prefix='en_US') if not cls.locales: raise nose.SkipTest("US English locale not available for testing")
class TestSeriesDatetimeValues: def test_dt_namespace_accessor(self): # GH 7207, 11128 # test .dt namespace accessor ok_for_period = PeriodArray._datetimelike_ops ok_for_period_methods = ["strftime", "to_timestamp", "asfreq"] ok_for_dt = DatetimeIndex._datetimelike_ops ok_for_dt_methods = [ "to_period", "to_pydatetime", "tz_localize", "tz_convert", "normalize", "strftime", "round", "floor", "ceil", "day_name", "month_name", ] ok_for_td = TimedeltaIndex._datetimelike_ops ok_for_td_methods = [ "components", "to_pytimedelta", "total_seconds", "round", "floor", "ceil", ] def get_expected(s, name): result = getattr(Index(s._values), prop) if isinstance(result, np.ndarray): if is_integer_dtype(result): result = result.astype("int64") elif not is_list_like(result): return result return Series(result, index=s.index, name=s.name) def compare(s, name): a = getattr(s.dt, prop) b = get_expected(s, prop) if not (is_list_like(a) and is_list_like(b)): assert a == b else: tm.assert_series_equal(a, b) # datetimeindex cases = [ Series(date_range("20130101", periods=5), name="xxx"), Series(date_range("20130101", periods=5, freq="s"), name="xxx"), Series(date_range("20130101 00:00:00", periods=5, freq="ms"), name="xxx"), ] for s in cases: for prop in ok_for_dt: # we test freq below if prop != "freq": compare(s, prop) for prop in ok_for_dt_methods: getattr(s.dt, prop) result = s.dt.to_pydatetime() assert isinstance(result, np.ndarray) assert result.dtype == object result = s.dt.tz_localize("US/Eastern") exp_values = DatetimeIndex(s.values).tz_localize("US/Eastern") expected = Series(exp_values, index=s.index, name="xxx") tm.assert_series_equal(result, expected) tz_result = result.dt.tz assert str(tz_result) == "US/Eastern" freq_result = s.dt.freq assert freq_result == DatetimeIndex(s.values, freq="infer").freq # let's localize, then convert result = s.dt.tz_localize("UTC").dt.tz_convert("US/Eastern") exp_values = (DatetimeIndex( s.values).tz_localize("UTC").tz_convert("US/Eastern")) expected = Series(exp_values, index=s.index, name="xxx") tm.assert_series_equal(result, expected) # datetimeindex with tz s = Series(date_range("20130101", periods=5, tz="US/Eastern"), name="xxx") for prop in ok_for_dt: # we test freq below if prop != "freq": compare(s, prop) for prop in ok_for_dt_methods: getattr(s.dt, prop) result = s.dt.to_pydatetime() assert isinstance(result, np.ndarray) assert result.dtype == object result = s.dt.tz_convert("CET") expected = Series(s._values.tz_convert("CET"), index=s.index, name="xxx") tm.assert_series_equal(result, expected) tz_result = result.dt.tz assert str(tz_result) == "CET" freq_result = s.dt.freq assert freq_result == DatetimeIndex(s.values, freq="infer").freq # timedelta index cases = [ Series(timedelta_range("1 day", periods=5), index=list("abcde"), name="xxx"), Series(timedelta_range("1 day 01:23:45", periods=5, freq="s"), name="xxx"), Series( timedelta_range("2 days 01:23:45.012345", periods=5, freq="ms"), name="xxx", ), ] for s in cases: for prop in ok_for_td: # we test freq below if prop != "freq": compare(s, prop) for prop in ok_for_td_methods: getattr(s.dt, prop) result = s.dt.components assert isinstance(result, DataFrame) tm.assert_index_equal(result.index, s.index) result = s.dt.to_pytimedelta() assert isinstance(result, np.ndarray) assert result.dtype == object result = s.dt.total_seconds() assert isinstance(result, pd.Series) assert result.dtype == "float64" freq_result = s.dt.freq assert freq_result == TimedeltaIndex(s.values, freq="infer").freq # both index = date_range("20130101", periods=3, freq="D") s = Series(date_range("20140204", periods=3, freq="s"), index=index, name="xxx") exp = Series(np.array([2014, 2014, 2014], dtype="int64"), index=index, name="xxx") tm.assert_series_equal(s.dt.year, exp) exp = Series(np.array([2, 2, 2], dtype="int64"), index=index, name="xxx") tm.assert_series_equal(s.dt.month, exp) exp = Series(np.array([0, 1, 2], dtype="int64"), index=index, name="xxx") tm.assert_series_equal(s.dt.second, exp) exp = pd.Series([s[0]] * 3, index=index, name="xxx") tm.assert_series_equal(s.dt.normalize(), exp) # periodindex cases = [ Series(period_range("20130101", periods=5, freq="D"), name="xxx") ] for s in cases: for prop in ok_for_period: # we test freq below if prop != "freq": compare(s, prop) for prop in ok_for_period_methods: getattr(s.dt, prop) freq_result = s.dt.freq assert freq_result == PeriodIndex(s.values).freq # test limited display api def get_dir(s): results = [r for r in s.dt.__dir__() if not r.startswith("_")] return sorted(set(results)) s = Series(date_range("20130101", periods=5, freq="D"), name="xxx") results = get_dir(s) tm.assert_almost_equal(results, sorted(set(ok_for_dt + ok_for_dt_methods))) s = Series( period_range("20130101", periods=5, freq="D", name="xxx").astype(object)) results = get_dir(s) tm.assert_almost_equal( results, sorted(set(ok_for_period + ok_for_period_methods))) # 11295 # ambiguous time error on the conversions s = Series(pd.date_range("2015-01-01", "2016-01-01", freq="T"), name="xxx") s = s.dt.tz_localize("UTC").dt.tz_convert("America/Chicago") results = get_dir(s) tm.assert_almost_equal(results, sorted(set(ok_for_dt + ok_for_dt_methods))) exp_values = pd.date_range("2015-01-01", "2016-01-01", freq="T", tz="UTC").tz_convert("America/Chicago") expected = Series(exp_values, name="xxx") tm.assert_series_equal(s, expected) # no setting allowed s = Series(date_range("20130101", periods=5, freq="D"), name="xxx") with pytest.raises(ValueError, match="modifications"): s.dt.hour = 5 # trying to set a copy with pd.option_context("chained_assignment", "raise"): with pytest.raises(com.SettingWithCopyError): s.dt.hour[0] = 5 @pytest.mark.parametrize( "method, dates", [ ["round", ["2012-01-02", "2012-01-02", "2012-01-01"]], ["floor", ["2012-01-01", "2012-01-01", "2012-01-01"]], ["ceil", ["2012-01-02", "2012-01-02", "2012-01-02"]], ], ) def test_dt_round(self, method, dates): # round s = Series( pd.to_datetime([ "2012-01-01 13:00:00", "2012-01-01 12:01:00", "2012-01-01 08:00:00" ]), name="xxx", ) result = getattr(s.dt, method)("D") expected = Series(pd.to_datetime(dates), name="xxx") tm.assert_series_equal(result, expected) def test_dt_round_tz(self): s = Series( pd.to_datetime([ "2012-01-01 13:00:00", "2012-01-01 12:01:00", "2012-01-01 08:00:00" ]), name="xxx", ) result = s.dt.tz_localize("UTC").dt.tz_convert("US/Eastern").dt.round( "D") exp_values = pd.to_datetime(["2012-01-01", "2012-01-01", "2012-01-01"]).tz_localize("US/Eastern") expected = Series(exp_values, name="xxx") tm.assert_series_equal(result, expected) @pytest.mark.parametrize("method", ["ceil", "round", "floor"]) def test_dt_round_tz_ambiguous(self, method): # GH 18946 round near "fall back" DST df1 = pd.DataFrame( [ pd.to_datetime("2017-10-29 02:00:00+02:00", utc=True), pd.to_datetime("2017-10-29 02:00:00+01:00", utc=True), pd.to_datetime("2017-10-29 03:00:00+01:00", utc=True), ], columns=["date"], ) df1["date"] = df1["date"].dt.tz_convert("Europe/Madrid") # infer result = getattr(df1.date.dt, method)("H", ambiguous="infer") expected = df1["date"] tm.assert_series_equal(result, expected) # bool-array result = getattr(df1.date.dt, method)("H", ambiguous=[True, False, False]) tm.assert_series_equal(result, expected) # NaT result = getattr(df1.date.dt, method)("H", ambiguous="NaT") expected = df1["date"].copy() expected.iloc[0:2] = pd.NaT tm.assert_series_equal(result, expected) # raise with pytest.raises(pytz.AmbiguousTimeError): getattr(df1.date.dt, method)("H", ambiguous="raise") @pytest.mark.parametrize( "method, ts_str, freq", [ ["ceil", "2018-03-11 01:59:00-0600", "5min"], ["round", "2018-03-11 01:59:00-0600", "5min"], ["floor", "2018-03-11 03:01:00-0500", "2H"], ], ) def test_dt_round_tz_nonexistent(self, method, ts_str, freq): # GH 23324 round near "spring forward" DST s = Series([pd.Timestamp(ts_str, tz="America/Chicago")]) result = getattr(s.dt, method)(freq, nonexistent="shift_forward") expected = Series( [pd.Timestamp("2018-03-11 03:00:00", tz="America/Chicago")]) tm.assert_series_equal(result, expected) result = getattr(s.dt, method)(freq, nonexistent="NaT") expected = Series([pd.NaT]).dt.tz_localize(result.dt.tz) tm.assert_series_equal(result, expected) with pytest.raises(pytz.NonExistentTimeError, match="2018-03-11 02:00:00"): getattr(s.dt, method)(freq, nonexistent="raise") def test_dt_namespace_accessor_categorical(self): # GH 19468 dti = DatetimeIndex(["20171111", "20181212"]).repeat(2) s = Series(pd.Categorical(dti), name="foo") result = s.dt.year expected = Series([2017, 2017, 2018, 2018], name="foo") tm.assert_series_equal(result, expected) def test_dt_tz_localize_categorical(self, tz_aware_fixture): # GH 27952 tz = tz_aware_fixture datetimes = pd.Series(["2019-01-01", "2019-01-01", "2019-01-02"], dtype="datetime64[ns]") categorical = datetimes.astype("category") result = categorical.dt.tz_localize(tz) expected = datetimes.dt.tz_localize(tz) tm.assert_series_equal(result, expected) def test_dt_tz_convert_categorical(self, tz_aware_fixture): # GH 27952 tz = tz_aware_fixture datetimes = pd.Series(["2019-01-01", "2019-01-01", "2019-01-02"], dtype="datetime64[ns, MET]") categorical = datetimes.astype("category") result = categorical.dt.tz_convert(tz) expected = datetimes.dt.tz_convert(tz) tm.assert_series_equal(result, expected) @pytest.mark.parametrize("accessor", ["year", "month", "day"]) def test_dt_other_accessors_categorical(self, accessor): # GH 27952 datetimes = pd.Series(["2018-01-01", "2018-01-01", "2019-01-02"], dtype="datetime64[ns]") categorical = datetimes.astype("category") result = getattr(categorical.dt, accessor) expected = getattr(datetimes.dt, accessor) tm.assert_series_equal(result, expected) def test_dt_accessor_no_new_attributes(self): # https://github.com/pandas-dev/pandas/issues/10673 s = Series(date_range("20130101", periods=5, freq="D")) with pytest.raises(AttributeError, match="You cannot add any new attribute"): s.dt.xlabel = "a" @pytest.mark.parametrize("time_locale", [None] if tm.get_locales() is None else [None] + tm.get_locales()) def test_dt_accessor_datetime_name_accessors(self, time_locale): # Test Monday -> Sunday and January -> December, in that sequence if time_locale is None: # If the time_locale is None, day-name and month_name should # return the english attributes expected_days = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", ] expected_months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ] else: with tm.set_locale(time_locale, locale.LC_TIME): expected_days = calendar.day_name[:] expected_months = calendar.month_name[1:] s = Series( date_range(freq="D", start=datetime(1998, 1, 1), periods=365)) english_days = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", ] for day, name, eng_name in zip(range(4, 11), expected_days, english_days): name = name.capitalize() assert s.dt.day_name(locale=time_locale)[day] == name s = s.append(Series([pd.NaT])) assert np.isnan(s.dt.day_name(locale=time_locale).iloc[-1]) s = Series(date_range(freq="M", start="2012", end="2013")) result = s.dt.month_name(locale=time_locale) expected = Series([month.capitalize() for month in expected_months]) # work around https://github.com/pandas-dev/pandas/issues/22342 result = result.str.normalize("NFD") expected = expected.str.normalize("NFD") tm.assert_series_equal(result, expected) for s_date, expected in zip(s, expected_months): result = s_date.month_name(locale=time_locale) expected = expected.capitalize() result = unicodedata.normalize("NFD", result) expected = unicodedata.normalize("NFD", expected) assert result == expected s = s.append(Series([pd.NaT])) assert np.isnan(s.dt.month_name(locale=time_locale).iloc[-1]) def test_strftime(self): # GH 10086 s = Series(date_range("20130101", periods=5)) result = s.dt.strftime("%Y/%m/%d") expected = Series([ "2013/01/01", "2013/01/02", "2013/01/03", "2013/01/04", "2013/01/05" ]) tm.assert_series_equal(result, expected) s = Series(date_range("2015-02-03 11:22:33.4567", periods=5)) result = s.dt.strftime("%Y/%m/%d %H-%M-%S") expected = Series([ "2015/02/03 11-22-33", "2015/02/04 11-22-33", "2015/02/05 11-22-33", "2015/02/06 11-22-33", "2015/02/07 11-22-33", ]) tm.assert_series_equal(result, expected) s = Series(period_range("20130101", periods=5)) result = s.dt.strftime("%Y/%m/%d") expected = Series([ "2013/01/01", "2013/01/02", "2013/01/03", "2013/01/04", "2013/01/05" ]) tm.assert_series_equal(result, expected) s = Series( period_range("2015-02-03 11:22:33.4567", periods=5, freq="s")) result = s.dt.strftime("%Y/%m/%d %H-%M-%S") expected = Series([ "2015/02/03 11-22-33", "2015/02/03 11-22-34", "2015/02/03 11-22-35", "2015/02/03 11-22-36", "2015/02/03 11-22-37", ]) tm.assert_series_equal(result, expected) s = Series(date_range("20130101", periods=5)) s.iloc[0] = pd.NaT result = s.dt.strftime("%Y/%m/%d") expected = Series( [np.nan, "2013/01/02", "2013/01/03", "2013/01/04", "2013/01/05"]) tm.assert_series_equal(result, expected) datetime_index = date_range("20150301", periods=5) result = datetime_index.strftime("%Y/%m/%d") expected = Index( [ "2015/03/01", "2015/03/02", "2015/03/03", "2015/03/04", "2015/03/05" ], dtype=np.object_, ) # dtype may be S10 or U10 depending on python version tm.assert_index_equal(result, expected) period_index = period_range("20150301", periods=5) result = period_index.strftime("%Y/%m/%d") expected = Index( [ "2015/03/01", "2015/03/02", "2015/03/03", "2015/03/04", "2015/03/05" ], dtype="=U10", ) tm.assert_index_equal(result, expected) s = Series( [datetime(2013, 1, 1, 2, 32, 59), datetime(2013, 1, 2, 14, 32, 1)]) result = s.dt.strftime("%Y-%m-%d %H:%M:%S") expected = Series(["2013-01-01 02:32:59", "2013-01-02 14:32:01"]) tm.assert_series_equal(result, expected) s = Series(period_range("20130101", periods=4, freq="H")) result = s.dt.strftime("%Y/%m/%d %H:%M:%S") expected = Series([ "2013/01/01 00:00:00", "2013/01/01 01:00:00", "2013/01/01 02:00:00", "2013/01/01 03:00:00", ]) s = Series(period_range("20130101", periods=4, freq="L")) result = s.dt.strftime("%Y/%m/%d %H:%M:%S.%l") expected = Series([ "2013/01/01 00:00:00.000", "2013/01/01 00:00:00.001", "2013/01/01 00:00:00.002", "2013/01/01 00:00:00.003", ]) tm.assert_series_equal(result, expected) @pytest.mark.parametrize( "data", [ DatetimeIndex(["2019-01-01", pd.NaT]), PeriodIndex(["2019-01-01", pd.NaT], dtype="period[D]"), ], ) def test_strftime_nat(self, data): # GH 29578 s = Series(data) result = s.dt.strftime("%Y-%m-%d") expected = Series(["2019-01-01", np.nan]) tm.assert_series_equal(result, expected) def test_valid_dt_with_missing_values(self): from datetime import date, time # GH 8689 s = Series(date_range("20130101", periods=5, freq="D")) s.iloc[2] = pd.NaT for attr in [ "microsecond", "nanosecond", "second", "minute", "hour", "day" ]: expected = getattr(s.dt, attr).copy() expected.iloc[2] = np.nan result = getattr(s.dt, attr) tm.assert_series_equal(result, expected) result = s.dt.date expected = Series( [ date(2013, 1, 1), date(2013, 1, 2), np.nan, date(2013, 1, 4), date(2013, 1, 5), ], dtype="object", ) tm.assert_series_equal(result, expected) result = s.dt.time expected = Series([time(0), time(0), np.nan, time(0), time(0)], dtype="object") tm.assert_series_equal(result, expected) def test_dt_accessor_api(self): # GH 9322 from pandas.core.indexes.accessors import ( CombinedDatetimelikeProperties, DatetimeProperties, ) assert Series.dt is CombinedDatetimelikeProperties s = Series(date_range("2000-01-01", periods=3)) assert isinstance(s.dt, DatetimeProperties) @pytest.mark.parametrize("ser", [ Series(np.arange(5)), Series(list("abcde")), Series(np.random.randn(5)) ]) def test_dt_accessor_invalid(self, ser): # GH#9322 check that series with incorrect dtypes don't have attr with pytest.raises(AttributeError, match="only use .dt accessor"): ser.dt assert not hasattr(ser, "dt") def test_dt_accessor_updates_on_inplace(self): s = Series(pd.date_range("2018-01-01", periods=10)) s[2] = None s.fillna(pd.Timestamp("2018-01-01"), inplace=True) result = s.dt.date assert result[0] == result[2] def test_between(self): s = Series(bdate_range("1/1/2000", periods=20).astype(object)) s[::2] = np.nan result = s[s.between(s[3], s[17])] expected = s[3:18].dropna() tm.assert_series_equal(result, expected) result = s[s.between(s[3], s[17], inclusive=False)] expected = s[5:16].dropna() tm.assert_series_equal(result, expected) def test_date_tz(self): # GH11757 rng = pd.DatetimeIndex( ["2014-04-04 23:56", "2014-07-18 21:24", "2015-11-22 22:14"], tz="US/Eastern", ) s = Series(rng) expected = Series( [date(2014, 4, 4), date(2014, 7, 18), date(2015, 11, 22)]) tm.assert_series_equal(s.dt.date, expected) tm.assert_series_equal(s.apply(lambda x: x.date()), expected) def test_datetime_understood(self): # Ensures it doesn't fail to create the right series # reported in issue#16726 series = pd.Series(pd.date_range("2012-01-01", periods=3)) offset = pd.offsets.DateOffset(days=6) result = series - offset expected = pd.Series( pd.to_datetime(["2011-12-26", "2011-12-27", "2011-12-28"])) tm.assert_series_equal(result, expected) 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_setitem_with_string_index(self): # GH 23451 x = pd.Series([1, 2, 3], index=["Date", "b", "other"]) x["Date"] = date.today() assert x.Date == date.today() assert x["Date"] == date.today() def test_setitem_with_different_tz(self): # GH#24024 ser = pd.Series(pd.date_range("2000", periods=2, tz="US/Central")) ser[0] = pd.Timestamp("2000", tz="US/Eastern") expected = pd.Series( [ pd.Timestamp("2000-01-01 00:00:00-05:00", tz="US/Eastern"), pd.Timestamp("2000-01-02 00:00:00-06:00", tz="US/Central"), ], dtype=object, ) tm.assert_series_equal(ser, expected)
class TestTimestampProperties: def test_properties_business(self): ts = Timestamp('2017-10-01', freq='B') control = Timestamp('2017-10-01') assert ts.dayofweek == 6 assert not ts.is_month_start # not a weekday assert not ts.is_quarter_start # not a weekday # Control case: non-business is month/qtr start assert control.is_month_start assert control.is_quarter_start ts = Timestamp('2017-09-30', freq='B') control = Timestamp('2017-09-30') assert ts.dayofweek == 5 assert not ts.is_month_end # not a weekday assert not ts.is_quarter_end # not a weekday # Control case: non-business is month/qtr start assert control.is_month_end assert control.is_quarter_end def test_fields(self): def check(value, equal): # that we are int like assert isinstance(value, int) assert value == equal # GH 10050 ts = Timestamp('2015-05-10 09:06:03.000100001') check(ts.year, 2015) check(ts.month, 5) check(ts.day, 10) check(ts.hour, 9) check(ts.minute, 6) check(ts.second, 3) msg = "'Timestamp' object has no attribute 'millisecond'" with pytest.raises(AttributeError, match=msg): ts.millisecond check(ts.microsecond, 100) check(ts.nanosecond, 1) check(ts.dayofweek, 6) check(ts.quarter, 2) check(ts.dayofyear, 130) check(ts.week, 19) check(ts.daysinmonth, 31) check(ts.daysinmonth, 31) # GH 13303 ts = Timestamp('2014-12-31 23:59:00-05:00', tz='US/Eastern') check(ts.year, 2014) check(ts.month, 12) check(ts.day, 31) check(ts.hour, 23) check(ts.minute, 59) check(ts.second, 0) msg = "'Timestamp' object has no attribute 'millisecond'" with pytest.raises(AttributeError, match=msg): ts.millisecond check(ts.microsecond, 0) check(ts.nanosecond, 0) check(ts.dayofweek, 2) check(ts.quarter, 4) check(ts.dayofyear, 365) check(ts.week, 1) check(ts.daysinmonth, 31) ts = Timestamp('2014-01-01 00:00:00+01:00') starts = ['is_month_start', 'is_quarter_start', 'is_year_start'] for start in starts: assert getattr(ts, start) ts = Timestamp('2014-12-31 23:59:59+01:00') ends = ['is_month_end', 'is_year_end', 'is_quarter_end'] for end in ends: assert getattr(ts, end) # GH 12806 @pytest.mark.parametrize('data', [ Timestamp('2017-08-28 23:00:00'), Timestamp('2017-08-28 23:00:00', tz='EST') ]) @pytest.mark.parametrize('time_locale', [None] if tm.get_locales() is None else [None] + tm.get_locales()) def test_names(self, data, time_locale): # GH 17354 # Test .weekday_name, .day_name(), .month_name with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): assert data.weekday_name == 'Monday' if time_locale is None: expected_day = 'Monday' expected_month = 'August' else: with tm.set_locale(time_locale, locale.LC_TIME): expected_day = calendar.day_name[0].capitalize() expected_month = calendar.month_name[8].capitalize() result_day = data.day_name(time_locale) result_month = data.month_name(time_locale) # Work around https://github.com/pandas-dev/pandas/issues/22342 # different normalizations expected_day = unicodedata.normalize("NFD", expected_day) expected_month = unicodedata.normalize("NFD", expected_month) result_day = unicodedata.normalize( "NFD", result_day, ) result_month = unicodedata.normalize("NFD", result_month) assert result_day == expected_day assert result_month == expected_month # Test NaT nan_ts = Timestamp(NaT) assert np.isnan(nan_ts.day_name(time_locale)) assert np.isnan(nan_ts.month_name(time_locale)) def test_is_leap_year(self, tz_naive_fixture): tz = tz_naive_fixture # GH 13727 dt = Timestamp('2000-01-01 00:00:00', tz=tz) assert dt.is_leap_year assert isinstance(dt.is_leap_year, bool) dt = Timestamp('1999-01-01 00:00:00', tz=tz) assert not dt.is_leap_year dt = Timestamp('2004-01-01 00:00:00', tz=tz) assert dt.is_leap_year dt = Timestamp('2100-01-01 00:00:00', tz=tz) assert not dt.is_leap_year def test_woy_boundary(self): # make sure weeks at year boundaries are correct d = datetime(2013, 12, 31) result = Timestamp(d).week expected = 1 # ISO standard assert result == expected d = datetime(2008, 12, 28) result = Timestamp(d).week expected = 52 # ISO standard assert result == expected d = datetime(2009, 12, 31) result = Timestamp(d).week expected = 53 # ISO standard assert result == expected d = datetime(2010, 1, 1) result = Timestamp(d).week expected = 53 # ISO standard assert result == expected d = datetime(2010, 1, 3) result = Timestamp(d).week expected = 53 # ISO standard assert result == expected result = np.array([ Timestamp(datetime(*args)).week for args in [(2000, 1, 1), (2000, 1, 2), (2005, 1, 1), (2005, 1, 2)] ]) assert (result == [52, 52, 53, 53]).all() def test_resolution(self): # GH#21336, GH#21365 dt = Timestamp('2100-01-01 00:00:00') assert dt.resolution == Timedelta(nanoseconds=1)
class TestDatetime64: def test_datetimeindex_accessors(self): dti_naive = pd.date_range(freq="D", start=datetime(1998, 1, 1), periods=365) # GH#13303 dti_tz = pd.date_range(freq="D", start=datetime(1998, 1, 1), periods=365, tz="US/Eastern") for dti in [dti_naive, dti_tz]: assert dti.year[0] == 1998 assert dti.month[0] == 1 assert dti.day[0] == 1 assert dti.hour[0] == 0 assert dti.minute[0] == 0 assert dti.second[0] == 0 assert dti.microsecond[0] == 0 assert dti.dayofweek[0] == 3 assert dti.dayofyear[0] == 1 assert dti.dayofyear[120] == 121 assert dti.weekofyear[0] == 1 assert dti.weekofyear[120] == 18 assert dti.quarter[0] == 1 assert dti.quarter[120] == 2 assert dti.days_in_month[0] == 31 assert dti.days_in_month[90] == 30 assert dti.is_month_start[0] assert not dti.is_month_start[1] assert dti.is_month_start[31] assert dti.is_quarter_start[0] assert dti.is_quarter_start[90] assert dti.is_year_start[0] assert not dti.is_year_start[364] assert not dti.is_month_end[0] assert dti.is_month_end[30] assert not dti.is_month_end[31] assert dti.is_month_end[364] assert not dti.is_quarter_end[0] assert not dti.is_quarter_end[30] assert dti.is_quarter_end[89] assert dti.is_quarter_end[364] assert not dti.is_year_end[0] assert dti.is_year_end[364] assert len(dti.year) == 365 assert len(dti.month) == 365 assert len(dti.day) == 365 assert len(dti.hour) == 365 assert len(dti.minute) == 365 assert len(dti.second) == 365 assert len(dti.microsecond) == 365 assert len(dti.dayofweek) == 365 assert len(dti.dayofyear) == 365 assert len(dti.weekofyear) == 365 assert len(dti.quarter) == 365 assert len(dti.is_month_start) == 365 assert len(dti.is_month_end) == 365 assert len(dti.is_quarter_start) == 365 assert len(dti.is_quarter_end) == 365 assert len(dti.is_year_start) == 365 assert len(dti.is_year_end) == 365 assert len(dti.weekday_name) == 365 dti.name = "name" # non boolean accessors -> return Index for accessor in DatetimeIndex._field_ops: res = getattr(dti, accessor) assert len(res) == 365 assert isinstance(res, Index) assert res.name == "name" # boolean accessors -> return array for accessor in DatetimeIndex._bool_ops: res = getattr(dti, accessor) assert len(res) == 365 assert isinstance(res, np.ndarray) # test boolean indexing res = dti[dti.is_quarter_start] exp = dti[[0, 90, 181, 273]] tm.assert_index_equal(res, exp) res = dti[dti.is_leap_year] exp = DatetimeIndex([], freq="D", tz=dti.tz, name="name") tm.assert_index_equal(res, exp) dti = pd.date_range(freq="BQ-FEB", start=datetime(1998, 1, 1), periods=4) assert sum(dti.is_quarter_start) == 0 assert sum(dti.is_quarter_end) == 4 assert sum(dti.is_year_start) == 0 assert sum(dti.is_year_end) == 1 # Ensure is_start/end accessors throw ValueError for CustomBusinessDay, bday_egypt = offsets.CustomBusinessDay(weekmask="Sun Mon Tue Wed Thu") dti = date_range(datetime(2013, 4, 30), periods=5, freq=bday_egypt) msg = "Custom business days is not supported by is_month_start" with pytest.raises(ValueError, match=msg): dti.is_month_start dti = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-03"]) assert dti.is_month_start[0] == 1 tests = [ (Timestamp("2013-06-01", freq="M").is_month_start, 1), (Timestamp("2013-06-01", freq="BM").is_month_start, 0), (Timestamp("2013-06-03", freq="M").is_month_start, 0), (Timestamp("2013-06-03", freq="BM").is_month_start, 1), (Timestamp("2013-02-28", freq="Q-FEB").is_month_end, 1), (Timestamp("2013-02-28", freq="Q-FEB").is_quarter_end, 1), (Timestamp("2013-02-28", freq="Q-FEB").is_year_end, 1), (Timestamp("2013-03-01", freq="Q-FEB").is_month_start, 1), (Timestamp("2013-03-01", freq="Q-FEB").is_quarter_start, 1), (Timestamp("2013-03-01", freq="Q-FEB").is_year_start, 1), (Timestamp("2013-03-31", freq="QS-FEB").is_month_end, 1), (Timestamp("2013-03-31", freq="QS-FEB").is_quarter_end, 0), (Timestamp("2013-03-31", freq="QS-FEB").is_year_end, 0), (Timestamp("2013-02-01", freq="QS-FEB").is_month_start, 1), (Timestamp("2013-02-01", freq="QS-FEB").is_quarter_start, 1), (Timestamp("2013-02-01", freq="QS-FEB").is_year_start, 1), (Timestamp("2013-06-30", freq="BQ").is_month_end, 0), (Timestamp("2013-06-30", freq="BQ").is_quarter_end, 0), (Timestamp("2013-06-30", freq="BQ").is_year_end, 0), (Timestamp("2013-06-28", freq="BQ").is_month_end, 1), (Timestamp("2013-06-28", freq="BQ").is_quarter_end, 1), (Timestamp("2013-06-28", freq="BQ").is_year_end, 0), (Timestamp("2013-06-30", freq="BQS-APR").is_month_end, 0), (Timestamp("2013-06-30", freq="BQS-APR").is_quarter_end, 0), (Timestamp("2013-06-30", freq="BQS-APR").is_year_end, 0), (Timestamp("2013-06-28", freq="BQS-APR").is_month_end, 1), (Timestamp("2013-06-28", freq="BQS-APR").is_quarter_end, 1), (Timestamp("2013-03-29", freq="BQS-APR").is_year_end, 1), (Timestamp("2013-11-01", freq="AS-NOV").is_year_start, 1), (Timestamp("2013-10-31", freq="AS-NOV").is_year_end, 1), (Timestamp("2012-02-01").days_in_month, 29), (Timestamp("2013-02-01").days_in_month, 28), ] for ts, value in tests: assert ts == value # GH 6538: Check that DatetimeIndex and its TimeStamp elements # return the same weekofyear accessor close to new year w/ tz dates = ["2013/12/29", "2013/12/30", "2013/12/31"] dates = DatetimeIndex(dates, tz="Europe/Brussels") expected = [52, 1, 1] assert dates.weekofyear.tolist() == expected assert [d.weekofyear for d in dates] == expected # GH 12806 @pytest.mark.parametrize("time_locale", [None] if tm.get_locales() is None else [None] + tm.get_locales()) def test_datetime_name_accessors(self, time_locale): # Test Monday -> Sunday and January -> December, in that sequence if time_locale is None: # If the time_locale is None, day-name and month_name should # return the english attributes expected_days = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", ] expected_months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ] else: with tm.set_locale(time_locale, locale.LC_TIME): expected_days = calendar.day_name[:] expected_months = calendar.month_name[1:] # GH#11128 dti = pd.date_range(freq="D", start=datetime(1998, 1, 1), periods=365) english_days = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", ] for day, name, eng_name in zip(range(4, 11), expected_days, english_days): name = name.capitalize() assert dti.weekday_name[day] == eng_name assert dti.day_name(locale=time_locale)[day] == name ts = Timestamp(datetime(2016, 4, day)) with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): assert ts.weekday_name == eng_name assert ts.day_name(locale=time_locale) == name dti = dti.append(DatetimeIndex([pd.NaT])) assert np.isnan(dti.day_name(locale=time_locale)[-1]) ts = Timestamp(pd.NaT) assert np.isnan(ts.day_name(locale=time_locale)) # GH#12805 dti = pd.date_range(freq="M", start="2012", end="2013") result = dti.month_name(locale=time_locale) expected = Index([month.capitalize() for month in expected_months]) # work around different normalization schemes # https://github.com/pandas-dev/pandas/issues/22342 result = result.str.normalize("NFD") expected = expected.str.normalize("NFD") tm.assert_index_equal(result, expected) for date, expected in zip(dti, expected_months): result = date.month_name(locale=time_locale) expected = expected.capitalize() result = unicodedata.normalize("NFD", result) expected = unicodedata.normalize("NFD", result) assert result == expected dti = dti.append(DatetimeIndex([pd.NaT])) assert np.isnan(dti.month_name(locale=time_locale)[-1]) def test_nanosecond_field(self): dti = DatetimeIndex(np.arange(10)) tm.assert_index_equal(dti.nanosecond, pd.Index(np.arange(10, dtype=np.int64)))
class TestSeriesDatetimeValues(): def test_dt_namespace_accessor(self): # GH 7207, 11128 # test .dt namespace accessor ok_for_period = PeriodArray._datetimelike_ops ok_for_period_methods = ['strftime', 'to_timestamp', 'asfreq'] ok_for_dt = DatetimeIndex._datetimelike_ops ok_for_dt_methods = [ 'to_period', 'to_pydatetime', 'tz_localize', 'tz_convert', 'normalize', 'strftime', 'round', 'floor', 'ceil', 'day_name', 'month_name' ] ok_for_td = TimedeltaIndex._datetimelike_ops ok_for_td_methods = [ 'components', 'to_pytimedelta', 'total_seconds', 'round', 'floor', 'ceil' ] def get_expected(s, name): result = getattr(Index(s._values), prop) if isinstance(result, np.ndarray): if is_integer_dtype(result): result = result.astype('int64') elif not is_list_like(result): return result return Series(result, index=s.index, name=s.name) def compare(s, name): a = getattr(s.dt, prop) b = get_expected(s, prop) if not (is_list_like(a) and is_list_like(b)): assert a == b else: tm.assert_series_equal(a, b) # datetimeindex cases = [ Series(date_range('20130101', periods=5), name='xxx'), Series(date_range('20130101', periods=5, freq='s'), name='xxx'), Series(date_range('20130101 00:00:00', periods=5, freq='ms'), name='xxx') ] for s in cases: for prop in ok_for_dt: # we test freq below if prop != 'freq': compare(s, prop) for prop in ok_for_dt_methods: getattr(s.dt, prop) result = s.dt.to_pydatetime() assert isinstance(result, np.ndarray) assert result.dtype == object result = s.dt.tz_localize('US/Eastern') exp_values = DatetimeIndex(s.values).tz_localize('US/Eastern') expected = Series(exp_values, index=s.index, name='xxx') tm.assert_series_equal(result, expected) tz_result = result.dt.tz assert str(tz_result) == 'US/Eastern' freq_result = s.dt.freq assert freq_result == DatetimeIndex(s.values, freq='infer').freq # let's localize, then convert result = s.dt.tz_localize('UTC').dt.tz_convert('US/Eastern') exp_values = (DatetimeIndex( s.values).tz_localize('UTC').tz_convert('US/Eastern')) expected = Series(exp_values, index=s.index, name='xxx') tm.assert_series_equal(result, expected) # datetimeindex with tz s = Series(date_range('20130101', periods=5, tz='US/Eastern'), name='xxx') for prop in ok_for_dt: # we test freq below if prop != 'freq': compare(s, prop) for prop in ok_for_dt_methods: getattr(s.dt, prop) result = s.dt.to_pydatetime() assert isinstance(result, np.ndarray) assert result.dtype == object result = s.dt.tz_convert('CET') expected = Series(s._values.tz_convert('CET'), index=s.index, name='xxx') tm.assert_series_equal(result, expected) tz_result = result.dt.tz assert str(tz_result) == 'CET' freq_result = s.dt.freq assert freq_result == DatetimeIndex(s.values, freq='infer').freq # timedelta index cases = [ Series(timedelta_range('1 day', periods=5), index=list('abcde'), name='xxx'), Series(timedelta_range('1 day 01:23:45', periods=5, freq='s'), name='xxx'), Series(timedelta_range('2 days 01:23:45.012345', periods=5, freq='ms'), name='xxx') ] for s in cases: for prop in ok_for_td: # we test freq below if prop != 'freq': compare(s, prop) for prop in ok_for_td_methods: getattr(s.dt, prop) result = s.dt.components assert isinstance(result, DataFrame) tm.assert_index_equal(result.index, s.index) result = s.dt.to_pytimedelta() assert isinstance(result, np.ndarray) assert result.dtype == object result = s.dt.total_seconds() assert isinstance(result, pd.Series) assert result.dtype == 'float64' freq_result = s.dt.freq assert freq_result == TimedeltaIndex(s.values, freq='infer').freq # both index = date_range('20130101', periods=3, freq='D') s = Series(date_range('20140204', periods=3, freq='s'), index=index, name='xxx') exp = Series(np.array([2014, 2014, 2014], dtype='int64'), index=index, name='xxx') tm.assert_series_equal(s.dt.year, exp) exp = Series(np.array([2, 2, 2], dtype='int64'), index=index, name='xxx') tm.assert_series_equal(s.dt.month, exp) exp = Series(np.array([0, 1, 2], dtype='int64'), index=index, name='xxx') tm.assert_series_equal(s.dt.second, exp) exp = pd.Series([s[0]] * 3, index=index, name='xxx') tm.assert_series_equal(s.dt.normalize(), exp) # periodindex cases = [ Series(period_range('20130101', periods=5, freq='D'), name='xxx') ] for s in cases: for prop in ok_for_period: # we test freq below if prop != 'freq': compare(s, prop) for prop in ok_for_period_methods: getattr(s.dt, prop) freq_result = s.dt.freq assert freq_result == PeriodIndex(s.values).freq # test limited display api def get_dir(s): results = [r for r in s.dt.__dir__() if not r.startswith('_')] return list(sorted(set(results))) s = Series(date_range('20130101', periods=5, freq='D'), name='xxx') results = get_dir(s) tm.assert_almost_equal( results, list(sorted(set(ok_for_dt + ok_for_dt_methods)))) s = Series( period_range('20130101', periods=5, freq='D', name='xxx').astype(object)) results = get_dir(s) tm.assert_almost_equal( results, list(sorted(set(ok_for_period + ok_for_period_methods)))) # 11295 # ambiguous time error on the conversions s = Series(pd.date_range('2015-01-01', '2016-01-01', freq='T'), name='xxx') s = s.dt.tz_localize('UTC').dt.tz_convert('America/Chicago') results = get_dir(s) tm.assert_almost_equal( results, list(sorted(set(ok_for_dt + ok_for_dt_methods)))) exp_values = pd.date_range('2015-01-01', '2016-01-01', freq='T', tz='UTC').tz_convert('America/Chicago') expected = Series(exp_values, name='xxx') tm.assert_series_equal(s, expected) # no setting allowed s = Series(date_range('20130101', periods=5, freq='D'), name='xxx') with pytest.raises(ValueError, match="modifications"): s.dt.hour = 5 # trying to set a copy with pd.option_context('chained_assignment', 'raise'): with pytest.raises(com.SettingWithCopyError): s.dt.hour[0] = 5 @pytest.mark.parametrize( 'method, dates', [['round', ['2012-01-02', '2012-01-02', '2012-01-01']], ['floor', ['2012-01-01', '2012-01-01', '2012-01-01']], ['ceil', ['2012-01-02', '2012-01-02', '2012-01-02']]]) def test_dt_round(self, method, dates): # round s = Series(pd.to_datetime([ '2012-01-01 13:00:00', '2012-01-01 12:01:00', '2012-01-01 08:00:00' ]), name='xxx') result = getattr(s.dt, method)('D') expected = Series(pd.to_datetime(dates), name='xxx') tm.assert_series_equal(result, expected) def test_dt_round_tz(self): s = Series(pd.to_datetime([ '2012-01-01 13:00:00', '2012-01-01 12:01:00', '2012-01-01 08:00:00' ]), name='xxx') result = ( s.dt.tz_localize('UTC').dt.tz_convert('US/Eastern').dt.round('D')) exp_values = pd.to_datetime(['2012-01-01', '2012-01-01', '2012-01-01']).tz_localize('US/Eastern') expected = Series(exp_values, name='xxx') tm.assert_series_equal(result, expected) @pytest.mark.parametrize('method', ['ceil', 'round', 'floor']) def test_dt_round_tz_ambiguous(self, method): # GH 18946 round near "fall back" DST df1 = pd.DataFrame([ pd.to_datetime('2017-10-29 02:00:00+02:00', utc=True), pd.to_datetime('2017-10-29 02:00:00+01:00', utc=True), pd.to_datetime('2017-10-29 03:00:00+01:00', utc=True) ], columns=['date']) df1['date'] = df1['date'].dt.tz_convert('Europe/Madrid') # infer result = getattr(df1.date.dt, method)('H', ambiguous='infer') expected = df1['date'] tm.assert_series_equal(result, expected) # bool-array result = getattr(df1.date.dt, method)('H', ambiguous=[True, False, False]) tm.assert_series_equal(result, expected) # NaT result = getattr(df1.date.dt, method)('H', ambiguous='NaT') expected = df1['date'].copy() expected.iloc[0:2] = pd.NaT tm.assert_series_equal(result, expected) # raise with pytest.raises(pytz.AmbiguousTimeError): getattr(df1.date.dt, method)('H', ambiguous='raise') @pytest.mark.parametrize('method, ts_str, freq', [['ceil', '2018-03-11 01:59:00-0600', '5min'], ['round', '2018-03-11 01:59:00-0600', '5min'], ['floor', '2018-03-11 03:01:00-0500', '2H']]) def test_dt_round_tz_nonexistent(self, method, ts_str, freq): # GH 23324 round near "spring forward" DST s = Series([pd.Timestamp(ts_str, tz='America/Chicago')]) result = getattr(s.dt, method)(freq, nonexistent='shift') expected = Series( [pd.Timestamp('2018-03-11 03:00:00', tz='America/Chicago')]) tm.assert_series_equal(result, expected) result = getattr(s.dt, method)(freq, nonexistent='NaT') expected = Series([pd.NaT]).dt.tz_localize(result.dt.tz) tm.assert_series_equal(result, expected) with pytest.raises(pytz.NonExistentTimeError, message='2018-03-11 02:00:00'): getattr(s.dt, method)(freq, nonexistent='raise') def test_dt_namespace_accessor_categorical(self): # GH 19468 dti = DatetimeIndex(['20171111', '20181212']).repeat(2) s = Series(pd.Categorical(dti), name='foo') result = s.dt.year expected = Series([2017, 2017, 2018, 2018], name='foo') tm.assert_series_equal(result, expected) def test_dt_accessor_no_new_attributes(self): # https://github.com/pandas-dev/pandas/issues/10673 s = Series(date_range('20130101', periods=5, freq='D')) with pytest.raises(AttributeError, match="You cannot add any new attribute"): s.dt.xlabel = "a" @pytest.mark.parametrize('time_locale', [None] if tm.get_locales() is None else [None] + tm.get_locales()) def test_dt_accessor_datetime_name_accessors(self, time_locale): # Test Monday -> Sunday and January -> December, in that sequence if time_locale is None: # If the time_locale is None, day-name and month_name should # return the english attributes expected_days = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ] expected_months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] else: with tm.set_locale(time_locale, locale.LC_TIME): expected_days = calendar.day_name[:] expected_months = calendar.month_name[1:] s = Series( date_range(freq='D', start=datetime(1998, 1, 1), periods=365)) english_days = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ] for day, name, eng_name in zip(range(4, 11), expected_days, english_days): name = name.capitalize() assert s.dt.weekday_name[day] == eng_name assert s.dt.day_name(locale=time_locale)[day] == name s = s.append(Series([pd.NaT])) assert np.isnan(s.dt.day_name(locale=time_locale).iloc[-1]) s = Series(date_range(freq='M', start='2012', end='2013')) result = s.dt.month_name(locale=time_locale) expected = Series([month.capitalize() for month in expected_months]) # work around https://github.com/pandas-dev/pandas/issues/22342 if not compat.PY2: result = result.str.normalize("NFD") expected = expected.str.normalize("NFD") tm.assert_series_equal(result, expected) for s_date, expected in zip(s, expected_months): result = s_date.month_name(locale=time_locale) expected = expected.capitalize() if not compat.PY2: result = unicodedata.normalize("NFD", result) expected = unicodedata.normalize("NFD", expected) assert result == expected s = s.append(Series([pd.NaT])) assert np.isnan(s.dt.month_name(locale=time_locale).iloc[-1]) def test_strftime(self): # GH 10086 s = Series(date_range('20130101', periods=5)) result = s.dt.strftime('%Y/%m/%d') expected = Series([ '2013/01/01', '2013/01/02', '2013/01/03', '2013/01/04', '2013/01/05' ]) tm.assert_series_equal(result, expected) s = Series(date_range('2015-02-03 11:22:33.4567', periods=5)) result = s.dt.strftime('%Y/%m/%d %H-%M-%S') expected = Series([ '2015/02/03 11-22-33', '2015/02/04 11-22-33', '2015/02/05 11-22-33', '2015/02/06 11-22-33', '2015/02/07 11-22-33' ]) tm.assert_series_equal(result, expected) s = Series(period_range('20130101', periods=5)) result = s.dt.strftime('%Y/%m/%d') expected = Series([ '2013/01/01', '2013/01/02', '2013/01/03', '2013/01/04', '2013/01/05' ]) tm.assert_series_equal(result, expected) s = Series( period_range('2015-02-03 11:22:33.4567', periods=5, freq='s')) result = s.dt.strftime('%Y/%m/%d %H-%M-%S') expected = Series([ '2015/02/03 11-22-33', '2015/02/03 11-22-34', '2015/02/03 11-22-35', '2015/02/03 11-22-36', '2015/02/03 11-22-37' ]) tm.assert_series_equal(result, expected) s = Series(date_range('20130101', periods=5)) s.iloc[0] = pd.NaT result = s.dt.strftime('%Y/%m/%d') expected = Series( ['NaT', '2013/01/02', '2013/01/03', '2013/01/04', '2013/01/05']) tm.assert_series_equal(result, expected) datetime_index = date_range('20150301', periods=5) result = datetime_index.strftime("%Y/%m/%d") expected = Index([ '2015/03/01', '2015/03/02', '2015/03/03', '2015/03/04', '2015/03/05' ], dtype=np.object_) # dtype may be S10 or U10 depending on python version tm.assert_index_equal(result, expected) period_index = period_range('20150301', periods=5) result = period_index.strftime("%Y/%m/%d") expected = Index([ '2015/03/01', '2015/03/02', '2015/03/03', '2015/03/04', '2015/03/05' ], dtype='=U10') tm.assert_index_equal(result, expected) s = Series( [datetime(2013, 1, 1, 2, 32, 59), datetime(2013, 1, 2, 14, 32, 1)]) result = s.dt.strftime('%Y-%m-%d %H:%M:%S') expected = Series(["2013-01-01 02:32:59", "2013-01-02 14:32:01"]) tm.assert_series_equal(result, expected) s = Series(period_range('20130101', periods=4, freq='H')) result = s.dt.strftime('%Y/%m/%d %H:%M:%S') expected = Series([ "2013/01/01 00:00:00", "2013/01/01 01:00:00", "2013/01/01 02:00:00", "2013/01/01 03:00:00" ]) s = Series(period_range('20130101', periods=4, freq='L')) result = s.dt.strftime('%Y/%m/%d %H:%M:%S.%l') expected = Series([ "2013/01/01 00:00:00.000", "2013/01/01 00:00:00.001", "2013/01/01 00:00:00.002", "2013/01/01 00:00:00.003" ]) tm.assert_series_equal(result, expected) def test_valid_dt_with_missing_values(self): from datetime import date, time # GH 8689 s = Series(date_range('20130101', periods=5, freq='D')) s.iloc[2] = pd.NaT for attr in [ 'microsecond', 'nanosecond', 'second', 'minute', 'hour', 'day' ]: expected = getattr(s.dt, attr).copy() expected.iloc[2] = np.nan result = getattr(s.dt, attr) tm.assert_series_equal(result, expected) result = s.dt.date expected = Series([ date(2013, 1, 1), date(2013, 1, 2), np.nan, date(2013, 1, 4), date(2013, 1, 5) ], dtype='object') tm.assert_series_equal(result, expected) result = s.dt.time expected = Series([time(0), time(0), np.nan, time(0), time(0)], dtype='object') tm.assert_series_equal(result, expected) def test_dt_accessor_api(self): # GH 9322 from pandas.core.indexes.accessors import ( CombinedDatetimelikeProperties, DatetimeProperties) assert Series.dt is CombinedDatetimelikeProperties s = Series(date_range('2000-01-01', periods=3)) assert isinstance(s.dt, DatetimeProperties) @pytest.mark.parametrize('ser', [ Series(np.arange(5)), Series(list('abcde')), Series(np.random.randn(5)) ]) def test_dt_accessor_invalid(self, ser): # GH#9322 check that series with incorrect dtypes don't have attr with pytest.raises(AttributeError, match="only use .dt accessor"): ser.dt assert not hasattr(ser, 'dt') def test_dt_accessor_updates_on_inplace(self): s = Series(pd.date_range('2018-01-01', periods=10)) s[2] = None s.fillna(pd.Timestamp('2018-01-01'), inplace=True) result = s.dt.date assert result[0] == result[2] def test_between(self): s = Series(bdate_range('1/1/2000', periods=20).astype(object)) s[::2] = np.nan result = s[s.between(s[3], s[17])] expected = s[3:18].dropna() assert_series_equal(result, expected) result = s[s.between(s[3], s[17], inclusive=False)] expected = s[5:16].dropna() assert_series_equal(result, expected) def test_date_tz(self): # GH11757 rng = pd.DatetimeIndex( ['2014-04-04 23:56', '2014-07-18 21:24', '2015-11-22 22:14'], tz="US/Eastern") s = Series(rng) expected = Series( [date(2014, 4, 4), date(2014, 7, 18), date(2015, 11, 22)]) assert_series_equal(s.dt.date, expected) assert_series_equal(s.apply(lambda x: x.date()), expected) def test_datetime_understood(self): # Ensures it doesn't fail to create the right series # reported in issue#16726 series = pd.Series(pd.date_range("2012-01-01", periods=3)) offset = pd.offsets.DateOffset(days=6) result = series - offset expected = pd.Series( pd.to_datetime(['2011-12-26', '2011-12-27', '2011-12-28'])) tm.assert_series_equal(result, expected) 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_setitem_with_string_index(self): # GH 23451 x = pd.Series([1, 2, 3], index=['Date', 'b', 'other']) x['Date'] = date.today() assert x.Date == date.today() assert x['Date'] == date.today() def test_setitem_with_different_tz(self): # GH#24024 ser = pd.Series(pd.date_range('2000', periods=2, tz="US/Central")) ser[0] = pd.Timestamp("2000", tz='US/Eastern') expected = pd.Series([ pd.Timestamp("2000-01-01 00:00:00-05:00", tz="US/Eastern"), pd.Timestamp("2000-01-02 00:00:00-06:00", tz="US/Central"), ], dtype=object) tm.assert_series_equal(ser, expected)
def setup_class(cls): cls.locales = tm.get_locales(prefix='en_US') if not cls.locales: # pragma: no cover pytest.skip("US English locale not available for testing")
class TestDatetime64(object): def test_datetimeindex_accessors(self): dti_naive = DatetimeIndex(freq='D', start=datetime(1998, 1, 1), periods=365) # GH 13303 dti_tz = DatetimeIndex(freq='D', start=datetime(1998, 1, 1), periods=365, tz='US/Eastern') for dti in [dti_naive, dti_tz]: assert dti.year[0] == 1998 assert dti.month[0] == 1 assert dti.day[0] == 1 assert dti.hour[0] == 0 assert dti.minute[0] == 0 assert dti.second[0] == 0 assert dti.microsecond[0] == 0 assert dti.dayofweek[0] == 3 assert dti.dayofyear[0] == 1 assert dti.dayofyear[120] == 121 assert dti.weekofyear[0] == 1 assert dti.weekofyear[120] == 18 assert dti.quarter[0] == 1 assert dti.quarter[120] == 2 assert dti.days_in_month[0] == 31 assert dti.days_in_month[90] == 30 assert dti.is_month_start[0] assert not dti.is_month_start[1] assert dti.is_month_start[31] assert dti.is_quarter_start[0] assert dti.is_quarter_start[90] assert dti.is_year_start[0] assert not dti.is_year_start[364] assert not dti.is_month_end[0] assert dti.is_month_end[30] assert not dti.is_month_end[31] assert dti.is_month_end[364] assert not dti.is_quarter_end[0] assert not dti.is_quarter_end[30] assert dti.is_quarter_end[89] assert dti.is_quarter_end[364] assert not dti.is_year_end[0] assert dti.is_year_end[364] assert len(dti.year) == 365 assert len(dti.month) == 365 assert len(dti.day) == 365 assert len(dti.hour) == 365 assert len(dti.minute) == 365 assert len(dti.second) == 365 assert len(dti.microsecond) == 365 assert len(dti.dayofweek) == 365 assert len(dti.dayofyear) == 365 assert len(dti.weekofyear) == 365 assert len(dti.quarter) == 365 assert len(dti.is_month_start) == 365 assert len(dti.is_month_end) == 365 assert len(dti.is_quarter_start) == 365 assert len(dti.is_quarter_end) == 365 assert len(dti.is_year_start) == 365 assert len(dti.is_year_end) == 365 assert len(dti.weekday_name) == 365 dti.name = 'name' # non boolean accessors -> return Index for accessor in DatetimeIndex._field_ops: res = getattr(dti, accessor) assert len(res) == 365 assert isinstance(res, Index) assert res.name == 'name' # boolean accessors -> return array for accessor in DatetimeIndex._bool_ops: res = getattr(dti, accessor) assert len(res) == 365 assert isinstance(res, np.ndarray) # test boolean indexing res = dti[dti.is_quarter_start] exp = dti[[0, 90, 181, 273]] tm.assert_index_equal(res, exp) res = dti[dti.is_leap_year] exp = DatetimeIndex([], freq='D', tz=dti.tz, name='name') tm.assert_index_equal(res, exp) dti = DatetimeIndex(freq='BQ-FEB', start=datetime(1998, 1, 1), periods=4) assert sum(dti.is_quarter_start) == 0 assert sum(dti.is_quarter_end) == 4 assert sum(dti.is_year_start) == 0 assert sum(dti.is_year_end) == 1 # Ensure is_start/end accessors throw ValueError for CustomBusinessDay, # CBD requires np >= 1.7 bday_egypt = offsets.CustomBusinessDay(weekmask='Sun Mon Tue Wed Thu') dti = date_range(datetime(2013, 4, 30), periods=5, freq=bday_egypt) pytest.raises(ValueError, lambda: dti.is_month_start) dti = DatetimeIndex(['2000-01-01', '2000-01-02', '2000-01-03']) assert dti.is_month_start[0] == 1 tests = [ (Timestamp('2013-06-01', freq='M').is_month_start, 1), (Timestamp('2013-06-01', freq='BM').is_month_start, 0), (Timestamp('2013-06-03', freq='M').is_month_start, 0), (Timestamp('2013-06-03', freq='BM').is_month_start, 1), (Timestamp('2013-02-28', freq='Q-FEB').is_month_end, 1), (Timestamp('2013-02-28', freq='Q-FEB').is_quarter_end, 1), (Timestamp('2013-02-28', freq='Q-FEB').is_year_end, 1), (Timestamp('2013-03-01', freq='Q-FEB').is_month_start, 1), (Timestamp('2013-03-01', freq='Q-FEB').is_quarter_start, 1), (Timestamp('2013-03-01', freq='Q-FEB').is_year_start, 1), (Timestamp('2013-03-31', freq='QS-FEB').is_month_end, 1), (Timestamp('2013-03-31', freq='QS-FEB').is_quarter_end, 0), (Timestamp('2013-03-31', freq='QS-FEB').is_year_end, 0), (Timestamp('2013-02-01', freq='QS-FEB').is_month_start, 1), (Timestamp('2013-02-01', freq='QS-FEB').is_quarter_start, 1), (Timestamp('2013-02-01', freq='QS-FEB').is_year_start, 1), (Timestamp('2013-06-30', freq='BQ').is_month_end, 0), (Timestamp('2013-06-30', freq='BQ').is_quarter_end, 0), (Timestamp('2013-06-30', freq='BQ').is_year_end, 0), (Timestamp('2013-06-28', freq='BQ').is_month_end, 1), (Timestamp('2013-06-28', freq='BQ').is_quarter_end, 1), (Timestamp('2013-06-28', freq='BQ').is_year_end, 0), (Timestamp('2013-06-30', freq='BQS-APR').is_month_end, 0), (Timestamp('2013-06-30', freq='BQS-APR').is_quarter_end, 0), (Timestamp('2013-06-30', freq='BQS-APR').is_year_end, 0), (Timestamp('2013-06-28', freq='BQS-APR').is_month_end, 1), (Timestamp('2013-06-28', freq='BQS-APR').is_quarter_end, 1), (Timestamp('2013-03-29', freq='BQS-APR').is_year_end, 1), (Timestamp('2013-11-01', freq='AS-NOV').is_year_start, 1), (Timestamp('2013-10-31', freq='AS-NOV').is_year_end, 1), (Timestamp('2012-02-01').days_in_month, 29), (Timestamp('2013-02-01').days_in_month, 28)] for ts, value in tests: assert ts == value # GH 6538: Check that DatetimeIndex and its TimeStamp elements # return the same weekofyear accessor close to new year w/ tz dates = ["2013/12/29", "2013/12/30", "2013/12/31"] dates = DatetimeIndex(dates, tz="Europe/Brussels") expected = [52, 1, 1] assert dates.weekofyear.tolist() == expected assert [d.weekofyear for d in dates] == expected # GH 12806 @pytest.mark.parametrize('time_locale', [ None] if tm.get_locales() is None else [None] + tm.get_locales()) def test_datetime_name_accessors(self, time_locale): # Test Monday -> Sunday and January -> December, in that sequence if time_locale is None: # If the time_locale is None, day-name and month_name should # return the english attributes expected_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] expected_months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] else: with tm.set_locale(time_locale, locale.LC_TIME): expected_days = calendar.day_name[:] expected_months = calendar.month_name[1:] # GH 11128 dti = DatetimeIndex(freq='D', start=datetime(1998, 1, 1), periods=365) english_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] for day, name, eng_name in zip(range(4, 11), expected_days, english_days): name = name.capitalize() assert dti.weekday_name[day] == eng_name assert dti.day_name(locale=time_locale)[day] == name ts = Timestamp(datetime(2016, 4, day)) with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): assert ts.weekday_name == eng_name assert ts.day_name(locale=time_locale) == name dti = dti.append(DatetimeIndex([pd.NaT])) assert np.isnan(dti.day_name(locale=time_locale)[-1]) ts = Timestamp(pd.NaT) assert np.isnan(ts.day_name(locale=time_locale)) # GH 12805 dti = DatetimeIndex(freq='M', start='2012', end='2013') result = dti.month_name(locale=time_locale) expected = Index([month.capitalize() for month in expected_months]) # work around different normalization schemes # https://github.com/pandas-dev/pandas/issues/22342 if not compat.PY2: result = result.str.normalize("NFD") expected = expected.str.normalize("NFD") tm.assert_index_equal(result, expected) for date, expected in zip(dti, expected_months): result = date.month_name(locale=time_locale) expected = expected.capitalize() if not compat.PY2: result = unicodedata.normalize("NFD", result) expected = unicodedata.normalize("NFD", result) assert result == expected dti = dti.append(DatetimeIndex([pd.NaT])) assert np.isnan(dti.month_name(locale=time_locale)[-1]) def test_nanosecond_field(self): dti = DatetimeIndex(np.arange(10)) tm.assert_index_equal(dti.nanosecond, pd.Index(np.arange(10, dtype=np.int64)))
def test_get_locales_prefix(self): if len(self.locales) == 1: raise nose.SkipTest("Only a single locale found, no point in " "trying to test filtering locale prefixes") first_locale = self.locales[0] assert len(tm.get_locales(prefix=first_locale[:2])) > 0
class TestTimestampProperties(object): def test_properties_business(self): ts = Timestamp('2017-10-01', freq='B') control = Timestamp('2017-10-01') assert ts.dayofweek == 6 assert not ts.is_month_start # not a weekday assert not ts.is_quarter_start # not a weekday # Control case: non-business is month/qtr start assert control.is_month_start assert control.is_quarter_start ts = Timestamp('2017-09-30', freq='B') control = Timestamp('2017-09-30') assert ts.dayofweek == 5 assert not ts.is_month_end # not a weekday assert not ts.is_quarter_end # not a weekday # Control case: non-business is month/qtr start assert control.is_month_end assert control.is_quarter_end def test_fields(self): def check(value, equal): # that we are int/long like assert isinstance(value, (int, long)) assert value == equal # GH 10050 ts = Timestamp('2015-05-10 09:06:03.000100001') check(ts.year, 2015) check(ts.month, 5) check(ts.day, 10) check(ts.hour, 9) check(ts.minute, 6) check(ts.second, 3) pytest.raises(AttributeError, lambda: ts.millisecond) check(ts.microsecond, 100) check(ts.nanosecond, 1) check(ts.dayofweek, 6) check(ts.quarter, 2) check(ts.dayofyear, 130) check(ts.week, 19) check(ts.daysinmonth, 31) check(ts.daysinmonth, 31) # GH 13303 ts = Timestamp('2014-12-31 23:59:00-05:00', tz='US/Eastern') check(ts.year, 2014) check(ts.month, 12) check(ts.day, 31) check(ts.hour, 23) check(ts.minute, 59) check(ts.second, 0) pytest.raises(AttributeError, lambda: ts.millisecond) check(ts.microsecond, 0) check(ts.nanosecond, 0) check(ts.dayofweek, 2) check(ts.quarter, 4) check(ts.dayofyear, 365) check(ts.week, 1) check(ts.daysinmonth, 31) ts = Timestamp('2014-01-01 00:00:00+01:00') starts = ['is_month_start', 'is_quarter_start', 'is_year_start'] for start in starts: assert getattr(ts, start) ts = Timestamp('2014-12-31 23:59:59+01:00') ends = ['is_month_end', 'is_year_end', 'is_quarter_end'] for end in ends: assert getattr(ts, end) # GH 12806 @pytest.mark.parametrize('data', [ Timestamp('2017-08-28 23:00:00'), Timestamp('2017-08-28 23:00:00', tz='EST') ]) @pytest.mark.parametrize('time_locale', [None] if tm.get_locales() is None else [None] + tm.get_locales()) def test_names(self, data, time_locale): # GH 17354 # Test .weekday_name, .day_name(), .month_name with tm.assert_produces_warning(DeprecationWarning, check_stacklevel=False): assert data.weekday_name == 'Monday' if time_locale is None: expected_day = 'Monday' expected_month = 'August' else: with tm.set_locale(time_locale, locale.LC_TIME): expected_day = calendar.day_name[0].capitalize() expected_month = calendar.month_name[8].capitalize() assert data.day_name(time_locale) == expected_day assert data.month_name(time_locale) == expected_month # Test NaT nan_ts = Timestamp(NaT) assert np.isnan(nan_ts.day_name(time_locale)) assert np.isnan(nan_ts.month_name(time_locale)) @pytest.mark.parametrize('tz', [None, 'UTC', 'US/Eastern', 'Asia/Tokyo']) def test_is_leap_year(self, tz): # GH 13727 dt = Timestamp('2000-01-01 00:00:00', tz=tz) assert dt.is_leap_year assert isinstance(dt.is_leap_year, bool) dt = Timestamp('1999-01-01 00:00:00', tz=tz) assert not dt.is_leap_year dt = Timestamp('2004-01-01 00:00:00', tz=tz) assert dt.is_leap_year dt = Timestamp('2100-01-01 00:00:00', tz=tz) assert not dt.is_leap_year def test_woy_boundary(self): # make sure weeks at year boundaries are correct d = datetime(2013, 12, 31) result = Timestamp(d).week expected = 1 # ISO standard assert result == expected d = datetime(2008, 12, 28) result = Timestamp(d).week expected = 52 # ISO standard assert result == expected d = datetime(2009, 12, 31) result = Timestamp(d).week expected = 53 # ISO standard assert result == expected d = datetime(2010, 1, 1) result = Timestamp(d).week expected = 53 # ISO standard assert result == expected d = datetime(2010, 1, 3) result = Timestamp(d).week expected = 53 # ISO standard assert result == expected result = np.array([ Timestamp(datetime(*args)).week for args in [(2000, 1, 1), (2000, 1, 2), (2005, 1, 1), (2005, 1, 2)] ]) assert (result == [52, 52, 53, 53]).all()
# -*- coding: utf-8 -*- import codecs import locale import os import pytest from pandas.compat import is_platform_windows import pandas.core.common as com import pandas.util.testing as tm _all_locales = tm.get_locales() or [] _current_locale = locale.getlocale() # Don't run any of these tests if we are on Windows or have no locales. pytestmark = pytest.mark.skipif(is_platform_windows() or not _all_locales, reason="Need non-Windows and locales") _skip_if_only_one_locale = pytest.mark.skipif( len(_all_locales) <= 1, reason="Need multiple locales for meaningful test") def test_can_set_locale_valid_set(): # Can set the default locale. assert tm.can_set_locale("") def test_can_set_locale_invalid_set(): # Cannot set an invalid locale. assert not tm.can_set_locale("non-existent_locale")