Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-36138: Improve docs about converting datetime.timedelta to scalars. #12137

Merged
merged 9 commits into from
Mar 16, 2019
Merged

bpo-36138: Improve docs about converting datetime.timedelta to scalars. #12137

merged 9 commits into from
Mar 16, 2019

Conversation

0xYasser
Copy link
Contributor

@0xYasser 0xYasser commented Mar 2, 2019

@scotchka
Copy link
Contributor

Perhaps add a note of caution about rounding errors, and that to get the highest precision, directly calculate the total microseconds as integers?

@ncoghlan
Copy link
Contributor

@scotchka There's an existing paragraph about the precision loss arising from the conversion to floating point in the total_seconds() documentation, so is your comment relating to the table entry?

In both cases, pointing to divmod as a way to avoid the precision loss would make sense.

@scotchka
Copy link
Contributor

scotchka commented Mar 14, 2019

@ncoghlan The doc currently says "Note that for very large time intervals (greater than 270 years on most platforms) this method will lose microsecond accuracy."

But in general, one can also get tripped up with a small interval, for a slightly different problem:

int(timedelta(0, 1, 1).total_seconds() * 1_000_000)  # convert to total microseconds
>>> 1000000

I'm no expert on computer arithmetic, but divmod does seem to avoid such issues. (To be honest, I'd probably carry out the integer multiplication and summation of the components the "long" way, just so I don't have to think about it 😃 )

@scotchka
Copy link
Contributor

Realized and confirmed that divmod is implemented with operations on the underlying integers.

@ncoghlan
Copy link
Contributor

@scotchka The precision loss in your short-interval example is coming from using a truncating conversion from float to int together with decimal-vs-binary floating point representations, not any loss of precision in the original total_seconds() conversion:

>>> from datetime import timedelta
>>> timedelta(0, 1, 1).total_seconds()
1.000001
>>> timedelta(0, 1, 1).total_seconds() * 1e6
1000000.9999999999
>>> int(timedelta(0, 1, 1).total_seconds() * 1e6)
1000000
>>> round(timedelta(0, 1, 1).total_seconds() * 1e6)
1000001

Given that, I'm going to merge this as is for master and 3.7, and if we decide to add extra references to divmod, that can go in a separate PR.

@miss-islington
Copy link
Contributor

Thanks @0xYasser for the PR, and @ncoghlan for merging it 🌮🎉.. I'm working now to backport this PR to: 3.7.
🐍🍒⛏🤖

@bedevere-bot
Copy link

GH-12362 is a backport of this pull request to the 3.7 branch.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Mar 16, 2019
…s. (pythonGH-12137)

Be explicit that timedelta division converts an overall duration to the interval
units given by the denominator.
(cherry picked from commit f40b4a0)

Co-authored-by: Yasser A <yalshalaan@gmail.com>
miss-islington added a commit that referenced this pull request Mar 16, 2019
…s. (GH-12137)

Be explicit that timedelta division converts an overall duration to the interval
units given by the denominator.
(cherry picked from commit f40b4a0)

Co-authored-by: Yasser A <yalshalaan@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants