[Python-Dev] How to round timestamps and durations?

Gregory P. Smith greg at krypto.org
Wed Feb 15 02:00:40 CET 2012


On Mon, Feb 13, 2012 at 4:59 AM, Victor Stinner
<victor.stinner at gmail.com> wrote:
> Hi,
>
> My work on the PEP 410 tries to unify the code to manipulate
> timestamps. The problem is that I'm unable to decide how to round
> these numbers.
>
> Functions using a resolution of 1 second (e.g. time.mktime) expects
> rounding towards zero (ROUND_HALF_DOWN), as does int(float). Example:
>
>>>> time.mktime(time.localtime(-1.9)), time.mktime(time.localtime(1.9))
> (-1.0, 1.0)

Otherwise known as truncation and the same behavior as C when
assigning a float to an int.

>
> datetime.datetime.fromtimestamp() rounds to nearest with ties going
> away from zero (ROUND_HALF_UP). Example:
>
>>>> datetime.datetime.fromtimestamp(-1.1e-6), datetime.datetime.fromtimestamp(1.1e-6)
> (datetime.datetime(1970, 1, 1, 0, 59, 59, 999999),
> datetime.datetime(1970, 1, 1, 1, 0, 0, 1))
>>>> datetime.datetime.fromtimestamp(-1.9e-6), datetime.datetime.fromtimestamp(1.9e-6)
> (datetime.datetime(1970, 1, 1, 0, 59, 59, 999998),
> datetime.datetime(1970, 1, 1, 1, 0, 0, 2))
>
> datetime.timedelta * float  and datetime.timedelta / float rounds to
> nearest with ties going to nearest even integer (ROUND_HALF_EVEN), as
> does round(). Example:
>
>>>> [(datetime.timedelta(microseconds=x) / 2.0).microseconds for x in range(6)]
> [0, 0, 1, 2, 2, 2]
>
> Should I also support multiple rounding methods depending on the
> operation and of the Python function? Should we always use the same
> rounding method?
>
> Antoine pointed me that ROUND_HALF_UP can produce timestamps "in the
> future", which is especially visible when using a resolution of 1
> second. I like this rounding method because it limits the loss of
> precision to an half unit: abs(rounded - timestamp) <= 0.5. But it can
> be "surprising".

I didn't know the other APIs ever rounded up so I find them a bit
surprising.  Realistically I expect any code out there that actually
cares one way or another outside of the int(time.time()) case will
care so I'd stick with that style of truncation (towards zero)
rounding in all situations myself.

-gps

> The rounding method should maybe be the same than int(float) (so
> ROUND_HALF_DOWN) to avoid surprising results for applications using
> int(time.time()) for example (I had such problem with rotated logs and
> test_logging).


More information about the Python-Dev mailing list