-1

I have times in a log that look like this:

1440498131.372625

What I've done using pytz is

utc = pytz.utc
for anra in raFromMCCS:
    fsecs = float(anra.time)
    isecs = int(fsecs)
    isec2 = int(fsecs * 1000)
    dt = datetime.utcfromtimestamp(isecs).replace(tzinfo=utc)
    #print (dt.year)
    dt2 = utc.localize(datetime(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, int((fsecs - isecs) * 1000000)))
    #      dt3 = datetime.utcfromtimestamp(isec2)
    print(dt, dt2)#, dt3)  

I left in the stupid dt3 attempt to show I'm new to all sorts of things here.

I know that dt2 gives me what I want but it seems like a roundabout way to get there. If you have a nicer solution, please let me know.

Thanks!

evernoob
  • 103
  • 7

1 Answers1

0

You could pass the float to fromtimestamp() directly:

d = datetime.fromtimestamp(1440498131.372625, utc)

If you know that the input is POSIX time (non-"right" timezone) then you could use the direct formula:

d = datetime(1970, 1, 1, tzinfo=utc) + timedelta(seconds=1440498131.372625)

It should provide a portable (wider) range for input timestamps. The rounding behavior should be more consistent between Python versions, see datetime.utcfromtimestamp rounds results incorrectly.

If input is a string; you could parse microseconds using strptime('%f'):

from datetime import datetime, timedelta

seconds, dot, us = "1440498131.372625".partition('.')
d = datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(seconds=int(seconds))
if dot:
    d = d.replace(microsecond=datetime.strptime(us, '%f').microsecond)

where timezone.utc is defined here. It also works if microseconds are represented using less than 6 digits e.g., ".372".

Only the last code example guarantees to preserve microseconds for any input timestamp.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • Thank you. The first one worked, or at least it gave me the same results (diffed the output) as the first way I was doing it. Much appreciated. – evernoob Sep 15 '15 at 20:04
  • Sorry, another comment for future ref: python3.4 and also, I ended up using return datetime(1970, 1, 1, tzinfo=utc) + timedelta(seconds=float(timeInSecs)) since the ref you provided stated this is the desired behavior of the other way... Once again, diff showed same results as the original way I did it, so I'm sticking with this one. – evernoob Sep 15 '15 at 20:27
  • @evernoob: to understand why you should use integers instead of floats in the general case, consider `int((datetime.max - datetime.min) / timedelta(microseconds=1))` vs. `(datetime.max - datetime.min) // timedelta(microseconds=1)` (the former is imprecise). Though for the range of everyday timestamps floats should have enough precision. – jfs Sep 15 '15 at 21:26