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

Victor Stinner victor.stinner at gmail.com
Mon Feb 13 13:59:18 CET 2012


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)

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".

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).

--

There is an issue on rounding timedelta:
http://bugs.python.org/issue8860

Victor


More information about the Python-Dev mailing list