Skip to content

Commit a3360e4

Browse files
committed
BUG: Avoid rounding when specifying unit and integer
Add tests Add whatsnew flake8
1 parent 44c822d commit a3360e4

File tree

3 files changed

+18
-9
lines changed

3 files changed

+18
-9
lines changed

doc/source/whatsnew/v0.23.0.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ Datetimelike
716716
- Bug in :class:`Timestamp` and :func:`to_datetime` where a string representing a barely out-of-bounds timestamp would be incorrectly rounded down instead of raising ``OutOfBoundsDatetime`` (:issue:`19382`)
717717
- Bug in :func:`Timestamp.floor` :func:`DatetimeIndex.floor` where time stamps far in the future and past were not rounded correctly (:issue:`19206`)
718718
- Bug in :func:`to_datetime` where passing an out-of-bounds datetime with ``errors='coerce'`` and ``utc=True`` would raise ``OutOfBoundsDatetime`` instead of parsing to ``NaT`` (:issue:`19612`)
719-
-
719+
- Bug in :class:`Timedelta`: where a numerical value with a unit would round values (:issue: `12690`)
720720

721721
Timezones
722722
^^^^^^^^^

pandas/_libs/tslibs/timedeltas.pyx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -200,22 +200,22 @@ cpdef inline int64_t cast_from_unit(object ts, object unit) except? -1:
200200

201201
if unit == 'D' or unit == 'd':
202202
m = 1000000000L * 86400
203-
p = 6
203+
p = 9
204204
elif unit == 'h':
205205
m = 1000000000L * 3600
206-
p = 6
206+
p = 9
207207
elif unit == 'm':
208208
m = 1000000000L * 60
209-
p = 6
209+
p = 9
210210
elif unit == 's':
211211
m = 1000000000L
212-
p = 6
212+
p = 9
213213
elif unit == 'ms':
214214
m = 1000000L
215-
p = 3
215+
p = 6
216216
elif unit == 'us':
217217
m = 1000L
218-
p = 0
218+
p = 3
219219
elif unit == 'ns' or unit is None:
220220
m = 1L
221221
p = 0
@@ -229,10 +229,10 @@ cpdef inline int64_t cast_from_unit(object ts, object unit) except? -1:
229229
# cast the unit, multiply base/frace separately
230230
# to avoid precision issues from float -> int
231231
base = <int64_t> ts
232-
frac = ts -base
232+
frac = ts - base
233233
if p:
234234
frac = round(frac, p)
235-
return <int64_t> (base *m) + <int64_t> (frac *m)
235+
return <int64_t> (base * m) + <int64_t> (frac * m)
236236

237237

238238
cdef inline _decode_if_necessary(object ts):

pandas/tests/scalar/test_timedelta.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,15 @@ def test_construction(self):
432432

433433
pytest.raises(ValueError, lambda: Timedelta(u'foo bar'))
434434

435+
@pytest.mark.parametrize("unit, value, expected", [
436+
('us', 9.999, 9999), ('ms', 9.999999, 9999999),
437+
('s', 9.999999999, 9999999999)])
438+
def test_rounding_on_int_unit_construction(self, unit, value, expected):
439+
result = Timedelta(value, unit=unit)
440+
assert result.value == expected
441+
result = Timedelta(str(value) + unit)
442+
assert result.value
443+
435444
def test_overflow_on_construction(self):
436445
# xref https://github.com/statsmodels/statsmodels/issues/3374
437446
value = pd.Timedelta('1day').value * 20169940

0 commit comments

Comments
 (0)