@@ -94,6 +94,8 @@ def wrapper(self, other, name=name):
94
94
95
95
if is_datetime_lhs or is_timedelta_lhs :
96
96
97
+ coerce = 'compat' if _np_version_under1p7 else True
98
+
97
99
# convert the argument to an ndarray
98
100
def convert_to_array (values ):
99
101
if not is_list_like (values ):
@@ -105,19 +107,20 @@ def convert_to_array(values):
105
107
values = tslib .array_to_datetime (values )
106
108
elif inferred_type in set (['timedelta' ]):
107
109
# have a timedelta, convert to to ns here
108
- if not (isinstance (values , pa .Array ) and com .is_timedelta64_dtype (values )):
109
- values = com ._possibly_cast_to_timedelta (values )
110
+ values = com ._possibly_cast_to_timedelta (values , coerce = coerce )
110
111
elif inferred_type in set (['timedelta64' ]):
111
112
# have a timedelta64, make sure dtype dtype is ns
112
- values = com ._possibly_cast_to_timedelta (values )
113
+ values = com ._possibly_cast_to_timedelta (values , coerce = coerce )
113
114
elif inferred_type in set (['integer' ]):
114
115
# py3 compat where dtype is 'm' but is an integer
115
116
if values .dtype .kind == 'm' :
116
117
values = values .astype ('timedelta64[ns]' )
118
+ else :
119
+ raise ValueError ("incompatible type for a datetime/timedelta operation" )
117
120
elif isinstance (values [0 ],DateOffset ):
118
121
# handle DateOffsets
119
122
values = pa .array ([ v .delta for v in values ])
120
- values = com ._possibly_cast_to_timedelta (values )
123
+ values = com ._possibly_cast_to_timedelta (values , coerce = coerce )
121
124
else :
122
125
values = pa .array (values )
123
126
return values
@@ -126,8 +129,8 @@ def convert_to_array(values):
126
129
lvalues = convert_to_array (lvalues )
127
130
rvalues = convert_to_array (rvalues )
128
131
129
- is_timedelta_rhs = com .is_timedelta64_dtype (rvalues )
130
132
is_datetime_rhs = com .is_datetime64_dtype (rvalues )
133
+ is_timedelta_rhs = com .is_timedelta64_dtype (rvalues ) or (not is_datetime_rhs and _np_version_under1p7 )
131
134
132
135
# 2 datetimes or 2 timedeltas
133
136
if (is_timedelta_lhs and is_timedelta_rhs ) or (is_datetime_lhs and
@@ -141,7 +144,6 @@ def convert_to_array(values):
141
144
142
145
dtype = 'timedelta64[ns]'
143
146
144
- # we may have to convert to object unfortunately here
145
147
mask = isnull (lvalues ) | isnull (rvalues )
146
148
if mask .any ():
147
149
def wrap_results (x ):
@@ -150,13 +152,20 @@ def wrap_results(x):
150
152
return x
151
153
152
154
# datetime and timedelta
153
- elif ( is_timedelta_lhs and is_datetime_rhs ) or ( is_timedelta_rhs and is_datetime_lhs ) :
155
+ elif is_timedelta_rhs and is_datetime_lhs :
154
156
155
157
if name not in ['__add__' ,'__sub__' ]:
156
- raise TypeError ("can only operate on a timedelta and a datetime for "
158
+ raise TypeError ("can only operate on a datetime with a rhs of a timedelta for "
157
159
"addition and subtraction, but the operator [%s] was passed" % name )
158
160
dtype = 'M8[ns]'
159
161
162
+ elif is_timedelta_lhs and is_datetime_rhs :
163
+
164
+ if name not in ['__add__' ]:
165
+ raise TypeError ("can only operate on a timedelta and a datetime for "
166
+ "addition, but the operator [%s] was passed" % name )
167
+ dtype = 'M8[ns]'
168
+
160
169
else :
161
170
raise ValueError ('cannot operate on a series with out a rhs '
162
171
'of a series/ndarray of type datetime64[ns] '
@@ -166,8 +175,11 @@ def wrap_results(x):
166
175
rvalues = rvalues .view ('i8' )
167
176
168
177
if isinstance (rvalues , Series ):
169
- lvalues = lvalues .values
170
- rvalues = rvalues .values
178
+
179
+ if hasattr (lvalues ,'values' ):
180
+ lvalues = lvalues .values
181
+ if hasattr (rvalues ,'values' ):
182
+ rvalues = rvalues .values
171
183
172
184
if self .index .equals (other .index ):
173
185
name = _maybe_match_name (self , other )
0 commit comments