Discussion:
outputting time in microseconds or milliseconds
matt.doolittle33
2013-08-02 10:54:32 UTC
Permalink
Hey everybody,

I am using 2.7 on Ubuntu 12.10. All I need to do is to print time with the microseconds. I have been looking at the docs and trying things for about half a day now with no success. Currently my code looks like this:

# write date and time and microseocnds
self.logfile.write('%s\t'%(str(strftime("%Y-%m-%d", ))))
self.logfile.write('%s\t'%(str(strftime("%H:%M:%S", ))))
self.logfile.write('%s\t'%(str(time())))

the output looks like this:

2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:44 00:00:00
2013-08-02 06:01:44 00:00:00

as you can see in the 2nd column the observations occur with 'fractional second' frequency, up to 8 or 9 per second. You can also see my latest attempt to get the microseconds in the third column is not working. It would really be great if python had a way to just tack the microseconds (actually i think milliseconds would be better) on to the second (in the 2nd column) as a fraction. If this is not possible I need the extra write statement for just the microseconds (millisecond if possible).

Any help will be much appreciated.
Thanks!
Dave Angel
2013-08-02 12:08:33 UTC
Permalink
Post by matt.doolittle33
Hey everybody,
I am using 2.7 on Ubuntu 12.10.
and what version of Python are you using? I don't know if it matters,
but it's useful to always supply both Python version and OS version.
Post by matt.doolittle33
All I need to do is to print time with the microseconds. I have been
looking at the docs and trying things for about half a day now with
# write date and time and microseocnds
self.logfile.write('%s\t'%(str(strftime("%Y-%m-%d", ))))
self.logfile.write('%s\t'%(str(strftime("%H:%M:%S", ))))
You've already got a problem: since this has two (implicit) calls to
localtime(). If this happens near enough to midnight, then your date
could be for one day, but the time for the following day.

You need to make a single call to get the time, and then format it into
one or more fields. if you didn't need sub-second information, it could
have been done by just using a longer spec for strftime().
Post by matt.doolittle33
self.logfile.write('%s\t'%(str(time())))
When I test str(time()) I get an output like this:
1375444314.484557
I can't imagine how you would get that third column from the line you
quote above.
Post by matt.doolittle33
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:44 00:00:00
2013-08-02 06:01:44 00:00:00
as you can see in the 2nd column the observations occur with 'fractional second' frequency, up to 8 or 9 per second. You can also see my latest attempt to get the microseconds in the third column is not working. It would really be great if python had a way to just tack the microseconds (actually i think milliseconds would be better) on to the second (in the 2nd column) as a fraction. If this is not possible I need the extra write statement for just the microseconds (millisecond if possible).
now = time() #make a single call to get the time in seconds (float)
localnow = localtime(now)

print(strftime("%Y-%m-%d\t%H:%M:%S\t", llocalnow))
print(now-int(now)) #obviously you should format this to get the
desired layout
--
DaveA
Chris Angelico
2013-08-02 12:50:42 UTC
Permalink
Post by Dave Angel
Post by matt.doolittle33
Hey everybody,
I am using 2.7 on Ubuntu 12.10.
and what version of Python are you using? I don't know if it matters,
but it's useful to always supply both Python version and OS version.
Looks to me like Python 2.7.

ChrisA
Ulrich Eckhardt
2013-08-02 11:59:30 UTC
Permalink
I am using 2.7 on Ubuntu 12.10. All I need to do is to print time with the microseconds.[...]
# write date and time and microseocnds
self.logfile.write('%s\t'%(str(strftime("%Y-%m-%d", ))))
self.logfile.write('%s\t'%(str(strftime("%H:%M:%S", ))))
self.logfile.write('%s\t'%(str(time())))
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
2013-08-02 06:01:43 00:00:00
The output here and the code are surely not the same, provided that
"time()" is the same as Python's "time.time()". That function will give
you the time as a floating-point number and with as much precision as is
available. You then only need the rest when dividing by one to get the
fractional seconds.

BTW:
1. You have a race condition, you are retrieving the time thrice, which
can and should yield different results for each call. Call it once, then
format the results in multiple steps if you want.
2. Python's strftime() gives you a string already, calling str() on it
is redundant. Also, formatting a string in order to then format it into
another string is unnecessary overhead. Further, '%s' will implicitly
invoke str() on the argument. Belt and suspenders anyone? :)

Good luck!

Uli
matt.doolittle33
2013-08-02 13:17:03 UTC
Permalink
so you are saying that

self.logfile.write('%s\t'%(str(time())))

should be:

self.logfile.write('%s\t'%(str(time.time())))

???
Thanks
Ulrich Eckhardt
2013-08-05 06:15:11 UTC
Permalink
Post by matt.doolittle33
so you are saying that
self.logfile.write('%s\t'%(str(time())))
self.logfile.write('%s\t'%(str(time.time())))
No, I'm not saying that. What I wanted to make clear is that your code
is impossible to understand as it stands, because nobody knows what
"time" refers to. My guess was that you had "from time import time,
strftime" somewhere in your code so that the "time" in your code refers
to the "time" function from Python's "time" module.

Uli
Skip Montanaro
2013-08-02 12:37:45 UTC
Permalink
Perhaps use datetime?
now = datetime.datetime.now()
now.isoformat()
'2013-08-02T07:37:08.430131'
now.strftime("%f")
'430131'

Skip
Steven D'Aprano
2013-08-02 12:35:13 UTC
Permalink
Post by matt.doolittle33
Hey everybody,
I am using 2.7 on Ubuntu 12.10. All I need to do is to print time with
the microseconds. I have been looking at the docs and trying things for
about half a day now with no success. Currently my code looks like
# write date and time and microseocnds
self.logfile.write('%s\t'%(str(strftime("%Y-%m-%d", ))))
self.logfile.write('%s\t'%(str(strftime("%H:%M:%S", ))))
self.logfile.write('%s\t'%(str(time())))
What's this time() function? Where does it come from, and what does it
do? By the look of it, it merely returns the string "00:00:00". The
time.time() function returns a number of seconds:

py> "%s" % time.time()
'1375445812.873546'

so I'm not sure what function you are calling there.

Also, you don't need to call str() before using the %s template, since
that automatically converts any object to a string. Besides,
time.strftime already returns a string.

You can replace all of those above lines with a single format string:

py> import time
py> print(time.strftime("%Y-%m-%d\t%H:%M:%S"))
2013-08-02 22:31:14


If you google for "strftime millisecond" with the search engine of your
choice:

https://duckduckgo.com/?q=strftime%20millisecond


you will find this bug report:

http://bugs.python.org/issue1982


Unfortunately, the %S.%f codes do not appear to work for me on Linux
using Python 2.6, 2.7 or 3.3. Perhaps you will have better luck.
--
Steven
matt.doolittle33
2013-08-02 15:09:15 UTC
Permalink
Post by Steven D'Aprano
Post by matt.doolittle33
Hey everybody,
I am using 2.7 on Ubuntu 12.10. All I need to do is to print time with
the microseconds. I have been looking at the docs and trying things for
about half a day now with no success. Currently my code looks like
# write date and time and microseocnds
self.logfile.write('%s\t'%(str(strftime("%Y-%m-%d", ))))
self.logfile.write('%s\t'%(str(strftime("%H:%M:%S", ))))
self.logfile.write('%s\t'%(str(time())))
What's this time() function? Where does it come from, and what does it
do? By the look of it, it merely returns the string "00:00:00". The
py> "%s" % time.time()
'1375445812.873546'
Post by matt.doolittle33
self.logfile.write('%s\t'%(str(time.time())))
matt.doolittle33
2013-08-02 14:18:54 UTC
Permalink
Post by Skip Montanaro
Perhaps use datetime?
now = datetime.datetime.now()
now.isoformat()
'2013-08-02T07:37:08.430131'
now.strftime("%f")
'430131'
Skip
Thanks Skip, what i currently i have is:

dt = datetime.now()

and
self.logfile.write('%s\t'%(str(strftime("%Y-%m-%d", ))))
self.logfile.write('%s\t'%(str(strftime("%H:%M:%S", ))))
self.logfile.write('%s\t'%(str(dt.microsecond)))

what i get is this:

2013-08-02 09:52:20 312961
2013-08-02 09:52:20 313274
2013-08-02 09:52:20 313461
2013-08-02 09:52:20 313580
2013-08-02 09:52:20 498705
2013-08-02 09:52:20 508610
2013-08-02 09:52:20 508963
2013-08-02 09:52:20 509191
2013-08-02 09:52:20 509477
2013-08-02 09:52:20 509703
2013-08-02 09:52:20 509798
2013-08-02 09:52:20 509887
2013-08-02 09:52:20 509975
2013-08-02 09:52:20 511013
2013-08-02 09:52:20 511112
2013-08-02 09:52:20 678554
2013-08-02 09:52:20 687994
2013-08-02 09:52:20 688291
2013-08-02 09:52:20 688519
2013-08-02 09:52:20 688740
2013-08-02 09:52:20 688963

is the third column is only the microsecond? how could i get this to write with the rest of the time (the hh:mm:ss) ?
Skip Montanaro
2013-08-02 15:15:53 UTC
Permalink
Post by matt.doolittle33
is the third column is only the microsecond?
Yes.
Post by matt.doolittle33
how could i get this to write with the rest of the time (the hh:mm:ss) ?
It sounds like you really want the time formatted in a particular way,
not just the numeric value of one or more fields. Look at the
documentation for the strftime method of datetime objects for full
details:

http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior
Post by matt.doolittle33
import datetime
now = datetime.datetime.now()
now.strftime("%H:%M:%S.%f")
'10:14:36.526110'

Skip
matt.doolittle33
2013-08-04 11:30:08 UTC
Permalink
ok so now i import the module like this:

from time import strftime, time

i made the write statement like this:

self.logfile.write('%s\t'%(str(strftime("%Y-%m-%d", ))))
self.logfile.write('%s\t'%(str(strftime("%H:%M:%S", ))))
self.logfile.write('%s\t'%(str(time())))

(oh and btw,i know the code is hacker ugly).
and the output is this:

2013-08-03 23:59:34 1375588774.89
2013-08-03 23:59:35 1375588775.06
2013-08-03 23:59:35 1375588775.25
2013-08-03 23:59:35 1375588775.43
2013-08-03 23:59:35 1375588775.80
2013-08-03 23:59:35 1375588775.99
2013-08-03 23:59:35 1375588775.99
2013-08-03 23:59:35 1375588775.99
2013-08-03 23:59:35 1375588776.00
2013-08-03 23:59:36 1375588776.15
2013-08-03 23:59:36 1375588776.15
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.34
2013-08-03 23:59:36 1375588776.35
2013-08-03 23:59:36 1375588776.35
2013-08-03 23:59:36 1375588776.35

the first two columns are for eyes so if they are a microsecond apart it doesn't matter. the numbers in the third column are for calculating duration which is where i need the precision.

Why is it only giving me the centisecond precision? the docs say i should get microsecond precision with the code i put together.

Thanks!
Alain Ketterlin
2013-08-04 11:57:08 UTC
Permalink
Post by matt.doolittle33
self.logfile.write('%s\t'%(str(time())))
[...]
Post by matt.doolittle33
2013-08-03 23:59:34 1375588774.89
[...]
Post by matt.doolittle33
Why is it only giving me the centisecond precision? the docs say i
should get microsecond precision with the code i put together.
Because of str()'s default format. Use "%f" % (time()) (and maybe vary
the precision).

-- Alain.

P/S: using str() + string formatting is kind of overkill: either use
string format directives like %f, or use str() with simple string
concatenation -- the latter giving less control.
Dave Angel
2013-08-04 13:38:43 UTC
Permalink
Post by matt.doolittle33
from time import strftime, time
self.logfile.write('%s\t'%(str(strftime("%Y-%m-%d", ))))
self.logfile.write('%s\t'%(str(strftime("%H:%M:%S", ))))
self.logfile.write('%s\t'%(str(time())))
(oh and btw,i know the code is hacker ugly).
2013-08-03 23:59:34 1375588774.89
2013-08-03 23:59:35 1375588775.06
2013-08-03 23:59:35 1375588775.25
2013-08-03 23:59:35 1375588775.43
2013-08-03 23:59:35 1375588775.80
2013-08-03 23:59:35 1375588775.99
2013-08-03 23:59:35 1375588775.99
2013-08-03 23:59:35 1375588775.99
2013-08-03 23:59:35 1375588776.00
2013-08-03 23:59:36 1375588776.15
2013-08-03 23:59:36 1375588776.15
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.16
2013-08-03 23:59:36 1375588776.34
2013-08-03 23:59:36 1375588776.35
2013-08-03 23:59:36 1375588776.35
2013-08-03 23:59:36 1375588776.35
the first two columns are for eyes so if they are a microsecond apart it doesn't matter.
But if the time is close enough to midnight, they'll be a *day* apart,
as I (and others) said before. It's also hard to imagine why you
resist the good advice you've been getting about formatting. You can
do both the date and time with one call to strftime().
Post by matt.doolittle33
the numbers in the third column are for calculating duration which is
where i need the precision.
Why is it only giving me the centisecond precision? the docs say i should get microsecond precision with the code i put together.
Have you done any experimenting to decide which logic was losing those
extra digits? Sit in the debugger, and do a t = time.time()

Then investigate what t looks like,
by repr(t), str(t), and "something" %t

(for various values of "something")
....

from time import time, localtime, strftime

now = time() #make a single call to get the time in seconds (float)
localnow = localtime(now)

out12 = strftime("%Y-%m-%d\t%H:%M:%S\t", localnow)
out3 = "%.6f" % now
self.logfile.write(out12 + out3)

You still have the problem that out12 is in the local time zone, while
out3 is in DCT. But as you say, these are for different audiences, and
presumably you won't really be putting them in the same file.
--
DaveA
Roy Smith
2013-08-04 14:33:48 UTC
Permalink
In article <07f6b1c7-069d-458b-a9fe-ff30c09f2f2d at googlegroups.com>,
Post by matt.doolittle33
self.logfile.write('%s\t'%(str(time())))
[...]
1375588774.89
[...]
Why is it only giving me the centisecond precision? the docs say i should
get microsecond precision
When citing documentation, it's a good idea to provide a link to the
docs page, and/or a direct quote of what you read.

I'm looking at http://docs.python.org/2/library/time.html#time.time,
which says, "not all systems provide time with a better precision than 1
second". So, I don't know where you got the impression that you're
guaranteed microsecond precision.

Earlier in the thread, you did mention that you're on Ubuntu, and there
you do indeed get pretty good precision. I'm not 100% sure if it's good
to the microsecond (it appears to be), but it's certainly better than
centisecond.

Anyway, your problem appears to be that str(float) gives you two digits
after the decimal (at least for values in the range we're talking about
Post by matt.doolittle33
Post by Dave Angel
t = time.time()
str(t)
'1375626035.26'
Post by matt.doolittle33
Post by Dave Angel
repr(t)
'1375626035.260934'

I don't know anywhere that those behaviors are guaranteed, however. If
you want to make sure you print a float with 6 digits after the decimal,
Post by matt.doolittle33
Post by Dave Angel
'%.6f' % t
'1375626035.260934'

Of course, if the underlying system call that time.time() invokes
returns less precision than microseconds, some of those 6 digits may
always be zero. Or worse, garbage.

Taking a step back, you're probably better off using datetimes. You'll
Post by matt.doolittle33
Post by Dave Angel
print datetime.datetime.utcnow()
2013-08-04 14:33:09.255096

When I write an operating system, I'm going to have it keep time in
units of YiTp (Yobi Plank times).
matt.doolittle33
2013-08-08 02:51:47 UTC
Permalink
Post by Roy Smith
Taking a step back, you're probably better off using datetimes. You'll
i did:

from time import strftime, time
from datetime import datetime

now = datetime.now()

self.logfile.write('%s\t'%(strftime("%Y-%m-%d",)))
self.logfile.write('%s\t'%(now.strftime("%H:%M:%S.%f",)))

this gives me:

2013-08-04 14:01:27.906126
2013-08-04 14:01:28.052273
2013-08-04 14:01:28.058967
2013-08-04 14:01:28.243959
2013-08-04 14:01:28.251107
2013-08-04 14:01:28.251268
2013-08-04 14:01:28.251373
2013-08-04 14:01:28.251475
2013-08-04 14:01:28.424568
2013-08-04 14:01:28.612548
2013-08-04 14:01:28.616569
2013-08-04 14:01:28.616727
2013-08-04 14:01:28.792487
2013-08-04 14:01:28.796226

thats what i need. Thanks!
Skip Montanaro
2013-08-08 12:03:31 UTC
Permalink
Post by matt.doolittle33
from time import strftime, time
from datetime import datetime
now = datetime.now()
self.logfile.write('%s\t'%(strftime("%Y-%m-%d",)))
self.logfile.write('%s\t'%(now.strftime("%H:%M:%S.%f",)))
Note that you don't need the time module here. Datetime objects have
what you need all by themselves:

from datetime import datetime
now = datetime.now()
self.logfile.write('%s\t%s\n' % (now.strftime("%Y-%m-%d"),
now.strftime("%H:%M:%S.%f")))

The time module was historically the way Python did time, but it
wasn't at all object-oriented and provided no direct support for date
arithmetic. When Tim Peters wrote datetime, the world became a better
place. Cozy up to the datetime documentation and put the time module
aside.

Skip

Skip
Roy Smith
2013-08-08 13:30:29 UTC
Permalink
In article <mailman.349.1375963829.1251.python-list at python.org>,
Post by Skip Montanaro
When Tim Peters wrote datetime, the world became a better
place.
Lots of languages and databases have things called datetimes. It's easy
to be lulled into thinking that they're all the same, but they're not.
They all have slightly different ranges and precisions.

Just something to be aware of.

Loading...