0

I'm a bit stumped by this I'm not going to lie but I'm currently having an invalid argument error thrown at me every time I try to convert a 13 character epoch to a readable date. This works without issue earlier on within the script, the part is erroring out on is the following:

print (msgTime)
messageTime=datetime.utcfromtimestamp(msgTime)

The value of 'msgTime' is gathered from an SQL Database and is returned as : 1540406475702

The exact error I get is:

Traceback (most recent call last):
  File "script.py", line 380, in <module>
    messageTime=datetime.utcfromtimestamp(msgTime)
OSError: [Errno 22] Invalid argument

I know Its likely something silly or small but I just can't see what is up, does anyone have any ideas?

  • What is the type of msgTime? – Andrew Mar 04 '20 at 09:09
  • This might help: https://stackoverflow.com/questions/37494983/python-fromtimestamp-oserror – David Kooijman Mar 04 '20 at 09:10
  • read official docs here: https://docs.python.org/3/library/datetime.html your func is ok, but msgTime has wrong value; if you try with different number - it just works; there is explanation on typical gotchas as well. – Drako Mar 04 '20 at 09:16

1 Answers1

1

The eopch time wont include milliseconds so currently would only be 10 digits long. Yours is 13, you can get rid of the extra milliseconds by floor dividing by 1000

from datetime import datetime
msgTime = 1540406475702
print (msgTime)
messageTime=datetime.utcfromtimestamp(msgTime//1000)
print(messageTime)

OUTPUT

1540406475702
2018-10-24 18:41:15

UPDATE

Having looked at the source code of datetime and how it implements fromtimestamp if you wanted to pass milliseconds you can do it by passing the values as a float where the 3 digits after the decimal point represents the milliseconds. Below is an extract from the datetime module

@classmethod
def _fromtimestamp(cls, t, utc, tz):
    """Construct a datetime from a POSIX timestamp (like time.time()).
    A timezone info object may be passed in as well.
    """
    frac, t = _math.modf(t)
    us = round(frac * 1e6)
    if us >= 1000000:
        t += 1
        us -= 1000000
    elif us < 0:
        t -= 1
        us += 1000000

    converter = _time.gmtime if utc else _time.localtime
    y, m, d, hh, mm, ss, weekday, jday, dst = converter(t)
    ss = min(ss, 59)    # clamp out leap seconds if the platform has them
    result = cls(y, m, d, hh, mm, ss, us, tz)

So you can pass milli / micro seconds if you pass them as the digits after the decimal place. Is it possible when this was working before that your epoch was second followed by a decimal place then the milliseconds?

from datetime import datetime
msgTime = 1540406475.702
print (msgTime)
messageTime=datetime.utcfromtimestamp(msgTime)
print(messageTime)

OUTPUT

1540406475.702
2018-10-24 18:41:15.702000
Chris Doyle
  • 10,703
  • 2
  • 23
  • 42
  • Thanks sorry for this.. Weirdly this worked before for a 13 character timestamp that was throwing me off.. –  Mar 04 '20 at 10:00
  • Without sounding to blunt i dont see how thats possible based on your current code. – Chris Doyle Mar 04 '20 at 10:16
  • @TrueSlawter This was still bugging me so i had a look at the source code for datetime. Is it possible that when it worked before your epoch was coming as `1540406475.702` as datetime will happily process that and calculate in the milliseconds etc. So is it coming now as `1540406475702` instead? because the only way dateimte identifies milli / nano seconds in an epoch is if they are after the decimal place. – Chris Doyle Mar 04 '20 at 11:04
  • It does appear that was the case Chris! thank you once again and sorry for wasting your time and so on. –  Mar 06 '20 at 09:12
  • @TrueSlawter you are welcome and it wasnt a waste of time. I also learned from it as had never really looked at the date time implementation before so i got something out of it too. – Chris Doyle Mar 06 '20 at 11:11