-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
FIX BUG: Timestamp __add__/__sub__ DateOffset with nanoseconds lost. #43968
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
2208507
ee19a4d
3e38ab2
5718e4f
e1ae149
326790b
83453da
ae4b133
a43030d
22cadbf
1c89c03
a2ad274
9bc6e97
c9ddf14
4780316
1fecfa6
e92c1a9
006c073
ab064b4
8e42c64
5ca3472
37d19b5
5acad37
9cda54a
0ee9a6f
860a62b
4600a64
8cf5746
a210baf
98646cd
e899fbe
906f546
24fe768
209ba9e
f56f52b
3f49876
b7297ef
5cbae96
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -83,6 +83,7 @@ from pandas._libs.tslibs.np_datetime cimport ( | |
from pandas._libs.tslibs.np_datetime import OutOfBoundsDatetime | ||
|
||
from pandas._libs.tslibs.offsets cimport ( | ||
is_dateoffset_object, | ||
is_offset_object, | ||
to_offset, | ||
) | ||
|
@@ -283,8 +284,11 @@ cdef class _Timestamp(ABCTimestamp): | |
cdef: | ||
int64_t nanos = 0 | ||
|
||
if is_dateoffset_object(other): | ||
jreback marked this conversation as resolved.
Show resolved
Hide resolved
|
||
nanos += other.nanoseconds | ||
other = other._offset | ||
if is_any_td_scalar(other): | ||
nanos = delta_to_nanoseconds(other) | ||
nanos += delta_to_nanoseconds(other) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are there any cases that go through the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If a case go through the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Doesn't it sometimes convert to a relativedelta object (which isnt a td_scalar)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jbrockmendel According to the codes below, we can see self._offset is a relativedelta object only if there is no nanosecond / nanoseconds keyword parameter. kwds_no_nanos = dict(
(k, v) for k, v in kwds.items()
if k not in ('nanosecond', 'nanoseconds')
)
# TODO: Are nanosecond and nanoseconds allowed somewhere?
_kwds_use_relativedelta = ('years', 'months', 'weeks', 'days',
'year', 'month', 'week', 'day', 'weekday',
'hour', 'minute', 'second', 'microsecond')
use_relativedelta = False
if len(kwds_no_nanos) > 0:
if any(k in _kwds_use_relativedelta for k in kwds_no_nanos):
offset = relativedelta(**kwds_no_nanos)
use_relativedelta = True |
||
result = type(self)(self.value + nanos, tz=self.tzinfo) | ||
if result is not NaT: | ||
result._set_freq(self._freq) # avoid warning in constructor | ||
|
@@ -307,7 +311,6 @@ cdef class _Timestamp(ABCTimestamp): | |
elif not isinstance(self, _Timestamp): | ||
# cython semantics, args have been switched and this is __radd__ | ||
return other.__add__(self) | ||
|
||
return NotImplemented | ||
|
||
def __sub__(self, other): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add a docstring, specifically make it clear when to use this vs is_offset_object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, that makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the comment you have here is not useful, add a doc-string not dependent on a particular patch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this function is not that necessary. It could be enough by using
is_offset_object(obj) and hasattr(obj, "nanoseconds")
to determine the need to deal with "nanoseconds".There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When calling
_TimeStamp.__add__(self, other)
with other is an Offset object, it can not meet any condition of the if-else chain. And it will call_TimeStamp.__add__(self, other._offset)
instead. I cannot find where this logic is implemented, but I guess we could explicitly check the Offset type in the if-else chain.