This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients aconrad, belopolsky, larry, mark.dickinson, r.david.murray, tbarbugli, tim.peters, trcarden, vivanov, vstinner
Date 2015-08-29.00:35:01
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1440808502.45.0.760158004602.issue23517@psf.upfronthosting.co.za>
In-reply-to
Content
Hi, I'm trying to write the rationale of the changes that I wrote in pytime.h in Python 3.3-3.5. The rounding of microseconds or nanoseconds is tricky. The code changed a lot and we used and we are still using various rounding methods depending on the case...

Alexander Belopolsky wrote:
> I believe the correct mode is "ROUND_HALF_EVEN".  This is the mode used by the builtin round() function: (...)

Right, round(float) and round(decimal.Decimal) uses the ROUND_HALF_EVEN rounding method.

On Python < 3.3, datetime.datetime.fromtimestamp(float) doesn't use exactly ROUND_HALF_EVEN, but it looks more to "round half away from zero" (the decimal module doesn't seem to support this exact rounding method).

The difference between ROUND_HALF_EVEN and "round half away from zero" is subtle. The two rounding methods only return a different result on the following case:

   divmod(t + us * 1e-6, 1.0)[1] * 1e6 == 0.5

where t and us are integers (t is a number of seconds created by mktime() and us is a number of microseconds in [0; 999999]).

I don't think that the case can occur. I failed to find such case for various values of t between 0 and 2**40, and us=0 or us=1. 1e-6 (10^-6 = 0.000001) cannot be represented exactly in base 2 (IEEE 754).

--

To move forward, we should agree on which rounding method datetime.datetime.fromtimestamp() should use, implement it in pytime.c (add a constant in pytime.h, implement it in pytime.c, and then write unit tests in test_time.py), and then use it in datetime.datetime.fromtimestamp().

IMHO we should only modify the rounding method used by datetime.datetime.fromtimestamp() and datetime.datetime.utcfromtimestamp(), other functions use the "right" rounding method.
History
Date User Action Args
2015-08-29 00:35:02vstinnersetrecipients: + vstinner, tim.peters, mark.dickinson, belopolsky, larry, r.david.murray, aconrad, vivanov, tbarbugli, trcarden
2015-08-29 00:35:02vstinnersetmessageid: <1440808502.45.0.760158004602.issue23517@psf.upfronthosting.co.za>
2015-08-29 00:35:02vstinnerlinkissue23517 messages
2015-08-29 00:35:01vstinnercreate