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