BUG: Timedelta components rounded by float imprecision · Issue #31354 · pandas-dev/pandas (original) (raw)
Problem description
It appears that there is some premature rounding happening in the Timedelta
constructor that makes it so the unit-adjusted sums of the days
, seconds
, microseconds
and nanoseconds
attributes do not sum to the total number of nanoseconds. A fundamental assumption of the datetime.timedelta
type (and breaking this assumption breaks Liskov substitutability) is that the total time difference at the precision of microseconds can be represented by summing up the unit-adjusted days
, seconds
and microseconds
attributes, and it's how datetime.total_seconds()
works.
I believe that this is the root cause of issue #31043, which was "fixed" with what is essentially a workaround in PR #31155, as I mentioned in this comment.
At the moment the most obvious effect is that bug #31043 only is fixed for recent versions of dateutil
, but presumably it will show up in other places where standard datetime
arithmetic is being used on pandas
timestamps.
Code Sample, a copy-pastable example if possible
def to_ns(td): ns = td.days * 86400 ns += td.seconds ns *= 1000000 ns += td.microseconds ns *= 1000 ns += td.nanoseconds return ns
td = timedelta(1552211999999999872, unit="ns") print(td.value) # 1552211999999999872 print(to_ns(td)) # 1552212000000000872
Actual output:
1552211999999999872
1552212000000000872
Expected output
1552211999999999872
1552211999999999872