From 544e8349a2bef04f4ed28fff8e3d9be4c70c790f Mon Sep 17 00:00:00 2001 From: Drew Massey Date: Thu, 7 Jun 2018 16:39:49 -0400 Subject: [PATCH 1/3] Added Function --- pandas/_libs/tslibs/timedeltas.pyx | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index 87dc371195b5b..9d1c075db178d 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -795,11 +795,14 @@ cdef class _Timedelta(timedelta): @property def resolution(self): - """ return a string representing the lowest resolution that we have """ + """ return a string representing the lowest resolution that we have. + note that this is nonstandard behavior. + to retrieve a timedelta object use the resolution_timedelta property + """ self._ensure_components() if self._ns: - return "N" + return elif self._us: return "U" elif self._ms: @@ -813,6 +816,28 @@ cdef class _Timedelta(timedelta): else: return "D" + @property + def resolution_timedelta(self): + """ return a timedelta object (rather than a string) + representing the lowest resolution we have. + to retireve a string use the resolution property. + """ + self._ensure_components() + if self._ns: + return timedelta(nanoseconds=1) + elif self._us: + return timedelta(microseconds=1) + elif self._ms: + return timedelta(milliseconds=1) + elif self._s: + return timedelta(seconds=1) + elif self._m: + return timedelta(minutes=1) + elif self._h: + return timedelta(hours=1) + else: + return timedelta(days=1) + @property def nanoseconds(self): """ From 75e4a855fb71ce998c01aa6bb83436f8691b74a8 Mon Sep 17 00:00:00 2001 From: Drew Massey Date: Tue, 12 Jun 2018 11:36:42 -0400 Subject: [PATCH 2/3] Timedelta resolution update --- pandas/_libs/tslibs/timedeltas.pyx | 23 +++++++++------ .../tests/scalar/timedelta/test_timedelta.py | 28 +++++++++++++++++++ 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index 9d1c075db178d..91c90263b0f43 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -795,14 +795,15 @@ cdef class _Timedelta(timedelta): @property def resolution(self): - """ return a string representing the lowest resolution that we have. - note that this is nonstandard behavior. - to retrieve a timedelta object use the resolution_timedelta property + """ + Return a string representing the lowest resolution that we have. + Note that this is nonstandard behavior. + To retrieve a timedelta object use the resolution_timedelta property """ self._ensure_components() if self._ns: - return + return "N" elif self._us: return "U" elif self._ms: @@ -818,13 +819,17 @@ cdef class _Timedelta(timedelta): @property def resolution_timedelta(self): - """ return a timedelta object (rather than a string) - representing the lowest resolution we have. - to retireve a string use the resolution property. """ + Return a timedelta object (rather than a string) + representing the lowest resolution we have. + to retrieve a string use the resolution property. + """ + self._ensure_components() if self._ns: - return timedelta(nanoseconds=1) + # At time of writing datetime.timedelta doesn't + # support nanoseconds as a keyword argument. + return timedelta(microseconds=0.1) elif self._us: return timedelta(microseconds=1) elif self._ms: @@ -836,7 +841,7 @@ cdef class _Timedelta(timedelta): elif self._h: return timedelta(hours=1) else: - return timedelta(days=1) + return timedelta(days=1) @property def nanoseconds(self): diff --git a/pandas/tests/scalar/timedelta/test_timedelta.py b/pandas/tests/scalar/timedelta/test_timedelta.py index 205fdf49d3e91..509de841b7730 100644 --- a/pandas/tests/scalar/timedelta/test_timedelta.py +++ b/pandas/tests/scalar/timedelta/test_timedelta.py @@ -588,3 +588,31 @@ def test_components(self): result = s.dt.components assert not result.iloc[0].isna().all() assert result.iloc[1].isna().all() + + def test_resolution(self): + # GH 21344 + assert Timedelta(nanoseconds=30).resolution == 'N' + # Note that datetime.timedelta doesn't offer + # finer resolution than microseconds + assert Timedelta(nanoseconds=30).resolution_timedelta.resolution == \ + timedelta(0, 0, 1) + + assert Timedelta(microseconds=30).resolution == 'U' + assert Timedelta(microseconds=30).resolution_timedelta.resolution == \ + timedelta(0, 0, 1) + + assert Timedelta(milliseconds=30).resolution == 'L' + assert Timedelta(milliseconds=30).resolution_timedelta.resolution == \ + timedelta(0, 0, 1) + + assert Timedelta(seconds=30).resolution == 'S' + assert Timedelta(seconds=30).resolution_timedelta.resolution == \ + timedelta(0, 0, 1) + + assert Timedelta(minutes=30).resolution == 'T' + assert Timedelta(minutes=30).resolution_timedelta.resolution == \ + timedelta(0, 0, 1) + + assert Timedelta(hours=2).resolution == 'H' + assert Timedelta(hours=2).resolution_timedelta.resolution == \ + timedelta(0, 0, 1) From 1c63c2abc7c7ff1e8c5dfb6dc0202157d8d18b1f Mon Sep 17 00:00:00 2001 From: Drew Massey Date: Tue, 12 Jun 2018 11:44:36 -0400 Subject: [PATCH 3/3] Updated what's new --- doc/source/whatsnew/v0.23.1.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v0.23.1.txt b/doc/source/whatsnew/v0.23.1.txt index db25bcf8113f5..51dcb324f538c 100644 --- a/doc/source/whatsnew/v0.23.1.txt +++ b/doc/source/whatsnew/v0.23.1.txt @@ -133,3 +133,4 @@ Bug Fixes - Tab completion on :class:`Index` in IPython no longer outputs deprecation warnings (:issue:`21125`) - Bug preventing pandas being used on Windows without C++ redistributable installed (:issue:`21106`) +- Add `resolution_timedelta` to :class:`Timedelta` to get non-string representations of resolution (:issue: `21344`)