Skip to content

BUG: Timedelta components rounded by float imprecision #31354

Closed
@pganssle

Description

@pganssle

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions