Skip to content

Commit 30eab2f

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

File tree

3 files changed

+19
-8
lines changed

3 files changed

+19
-8
lines changed

doc/source/whatsnew/v0.23.0.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +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+
- Bug in :class:`Timedelta`: where a numerical value with a unit would round values (:issue: `12690`)
719720
-
720721

721722
Timezones

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: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,16 @@ 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+
# GH 12690
440+
result = Timedelta(value, unit=unit)
441+
assert result.value == expected
442+
result = Timedelta(str(value) + unit)
443+
assert result.value
444+
435445
def test_overflow_on_construction(self):
436446
# xref https://github.com/statsmodels/statsmodels/issues/3374
437447
value = pd.Timedelta('1day').value * 20169940

0 commit comments

Comments
 (0)