# need to print seconds from the epoch including the millisecond

Roy Smith roy at panix.com
Mon Dec 30 15:22:21 CET 2013

```In article <mailman.4714.1388407860.18130.python-list at python.org>,
Ned Batchelder <ned at nedbatchelder.com> wrote:

> A float's str() includes two decimal points of precision

It's actually weirder than that.  What str() appears to do is print some
variable number of digits after the decimal place, depending on the
magnitude of the number, and then flips over to exponential notation at
some point.  All of this is in line with str()'s intent, which is to
produce a human-friendly string:

for i in range(15):
f = 10**i + 0.123456789
print "%-20s %-20s" % (str(f), repr(f))

\$ python float.py
1.123456789          1.123456789
10.123456789         10.123456789
100.123456789        100.123456789
1000.12345679        1000.123456789
10000.1234568        10000.123456789
100000.123457        100000.123456789
1000000.12346        1000000.123456789
10000000.1235        10000000.12345679
100000000.123        100000000.12345679
1000000000.12        1000000000.1234568
10000000000.1        10000000000.123457
1e+11                100000000000.12346
1e+12                1000000000000.1234
1e+13                10000000000000.123
1e+14                100000000000000.12

It just happens that for the range of values time.time() is returning
these days, two decimal digits is what you get.  Unix time rolled over
to this many digits on

>>> time.ctime(999999999)
'Sat Sep  8 21:46:39 2001'

so before then, str(time.time()) would have (presumably) generated 3
decimal digits.

Note that repr() also adjusts the number of digits after the decimal
place, but this is because it's run out of available hardware precision
(IEEE double precision is about 16 decimal digits).

Also note that while repr() is smart enough to stop when it runs out of
bits, the %f format specifier isn't:

>>> f = 10000000000000.123456789
>>> repr(f)
'10000000000000.123'
>>> "%.6f" % f
'10000000000000.123047'

[Ned, again]
> Luckily, you can decide how to format the float yourself:
> [...]
>      >>> print "%.4f" % time.time()
>      1388407726.1001

The problem here is that you have no guarantee here that all those
digits are meaningful.  I'm not sure what would happen on a machine
where the system clock only gives centisecond precision.

I would like to think "%.4f" % time.time() would always produce a string
with 4 digits after the decimal point, the last two of which were
guaranteed to be "0".  But not having such a box handy to test, that's
just a conjecture.  A much more pathological case would be that it
produces random garbage for the extra digits, which would make it appear
that you were getting more time precision than you really were.

All of which is a good reason to avoid raw timestamps and use datetime.
With a datatime object, somebody else has already worried about these
things for you.

PS: all the above examples were done with Python 2.7.1 on OSX 10.7.

```

More information about the Python-list mailing list