Skip to content

Commit 4b5c7aa

Browse files
committed
BUG: Fix irregular Timestamp arithmetic types pandas-dev#6543
1 parent 549a390 commit 4b5c7aa

File tree

3 files changed

+33
-9
lines changed

3 files changed

+33
-9
lines changed

doc/source/release.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ Bug Fixes
185185
- Bug in :meth:`DataFrame.replace` where nested dicts were erroneously
186186
depending on the order of dictionary keys and values (:issue:`5338`).
187187
- Perf issue in concatting with empty objects (:issue:`3259`)
188-
- Clarify sorting of ``sym_diff`` on ``Index``es with ``NaN``s (:isssue:`6444`)
188+
- Clarify sorting of ``sym_diff`` on ``Index``es with ``NaN``s (:issue:`6444`)
189189
- Regression in ``MultiIndex.from_product`` with a ``DatetimeIndex`` as input (:issue:`6439`)
190190
- Bug in ``str.extract`` when passed a non-default index (:issue:`6348`)
191191
- Bug in ``str.split`` when passed ``pat=None`` and ``n=1`` (:issue:`6466`)
@@ -207,6 +207,7 @@ Bug Fixes
207207
- Bug in ``pd.read_stata`` which would use the wrong data types and missing values (:issue:`6327`)
208208
- Bug in ``DataFrame.to_stata`` that lead to data loss in certain cases, and could exported using the
209209
wrong data types and missing values (:issue:`6335`)
210+
- Inconsistent types in Timestamp addition/subtraction (:issue:`6543`)
210211

211212

212213
pandas 0.13.1

pandas/tseries/tests/test_tslib.py

+26-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from pandas.core.api import Timestamp
99
from pandas.tslib import period_asfreq, period_ordinal
10+
from pandas.tseries.index import date_range
1011
from pandas.tseries.frequencies import get_freq
1112
from pandas import _np_version_under1p7
1213
import pandas.util.testing as tm
@@ -302,10 +303,32 @@ def test_period_ordinal_business_day(self):
302303
# Tuesday
303304
self.assertEqual(11418, period_ordinal(2013, 10, 8, 0, 0, 0, 0, 0, get_freq('B')))
304305

305-
class TestTomeStampOps(tm.TestCase):
306+
class TestTimestampOps(tm.TestCase):
306307
def test_timestamp_and_datetime(self):
307-
self.assertEqual((Timestamp(datetime.datetime(2013, 10,13)) - datetime.datetime(2013, 10,12)).days, 1)
308-
self.assertEqual((datetime.datetime(2013, 10, 12) - Timestamp(datetime.datetime(2013, 10,13))).days, -1)
308+
self.assertEqual((Timestamp(datetime.datetime(2013, 10, 13)) - datetime.datetime(2013, 10, 12)).days, 1)
309+
self.assertEqual((datetime.datetime(2013, 10, 12) - Timestamp(datetime.datetime(2013, 10, 13))).days, -1)
310+
311+
def test_addition_subtraction_types(self):
312+
# Assert on the types resulting from Timestamp +/- various date/time objects
313+
datetime_instance = datetime.datetime(2014, 3, 4)
314+
timedelta_instance = datetime.timedelta(seconds=1)
315+
# build a timestamp with a frequency, since then it supports addition/subtraction of integers
316+
timestamp_instance = date_range(datetime_instance, periods=1, freq='D')[0]
317+
318+
self.assertEqual(type(timestamp_instance + 1), Timestamp)
319+
self.assertEqual(type(timestamp_instance - 1), Timestamp)
320+
321+
# Timestamp + datetime not supported, though subtraction is supported and yields timedelta
322+
self.assertEqual(type(timestamp_instance - datetime_instance), datetime.timedelta)
323+
324+
self.assertEqual(type(timestamp_instance + timedelta_instance), Timestamp)
325+
self.assertEqual(type(timestamp_instance - timedelta_instance), Timestamp)
326+
327+
if not _np_version_under1p7:
328+
# Timestamp +/- datetime64 not supported, so not tested (could possibly assert error raised?)
329+
timedelta64_instance = np.timedelta64(1, 'D')
330+
self.assertEqual(type(timestamp_instance + timedelta64_instance), Timestamp)
331+
self.assertEqual(type(timestamp_instance - timedelta64_instance), Timestamp)
309332

310333
if __name__ == '__main__':
311334
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],

pandas/tslib.pyx

+5-5
Original file line numberDiff line numberDiff line change
@@ -700,11 +700,11 @@ cdef class _Timestamp(datetime):
700700
return result
701701

702702
def __sub__(self, other):
703-
if is_integer_object(other):
704-
neg_other = -other
705-
return self + neg_other
706-
# This calling convention is required
707-
return datetime.__sub__(self, other)
703+
if isinstance(other, datetime):
704+
return datetime.__sub__(self, other)
705+
706+
neg_other = -other
707+
return self + neg_other
708708

709709
cpdef _get_field(self, field):
710710
out = get_date_field(np.array([self.value], dtype=np.int64), field)

0 commit comments

Comments
 (0)