NealWalters
NealWalters

Reputation: 18207

Python - code to convert any epoch time to formatted datetime

Is there some universal way to convert any epoch time in Python 3.6 or 3.7. I got code working for one epoch time, but I'm calling various REST APIs, and some have more precision than others.

I got it working by dividing the specific time by 100000000. But if possible, I would like one function to convert epoch time, no matter how many digits it is. If that's not possible with a built-in function, then is the best way to test the number of digits, and just divide by the appropriate number.

Another post suggested using time.strftime but I couldn't get that to work.

I've seen several StackOver flow talk about the eror "OSError: [Errno 22] Invalid argument" which I get, but none addressed the concept of having one convert to handle all possible formats.

Example:

from datetime import datetime
import datetime as datetime1  #still confused about this 
                              #sometimes I use other functions that require the 
                              #the first import above. 
import time

epoch_time1 = 1598653800
epoch_time2   = 1598653800006864384
# epoch_time2   = 1598653800006864384 / 100000000  #this works 
quoteTimeDTObj1 = datetime1.datetime.fromtimestamp(epoch_time1)
#quoteTimeDTObj1 = time.strftime('%Y-%m-%d %H:%M:%S', epoch_time1)
print("quoteTimeDTObj1=" + str(quoteTimeDTObj1))

quoteTimeDTObj2 = datetime1.datetime.fromtimestamp(epoch_time2)
#quoteTimeDTObj2 = time.strftime('%Y-%m-%d %H:%M:%S', epoch_time2)
print("quoteTimeDTObj2=" + str(quoteTimeDTObj2))

Upvotes: 0

Views: 535

Answers (1)

Grismar
Grismar

Reputation: 31354

Something like this works, assuming you sometime receive epoch time in milliseconds and sometimes in nanoseconds:

from datetime import datetime


def epoch_to_dt(epoch_time):
    if epoch_time> 2147483647:
        return datetime.fromtimestamp(epoch_time / 100000000)
    else:
        return datetime.fromtimestamp(epoch_time)


print(epoch_to_dt(1598653800))
print(epoch_to_dt(1598653800006864384))

Result:

2020-08-29 08:30:00
2020-08-29 08:30:00.006864

The datetime module doesn't want to do what's done here: assume a large value automatically means nanoseconds are intended. The standard epoch time is milliseconds as either an integer value, or as a floating point value with the fractional part indicating parts smaller than a millisecond, which I would recommend using in your own code as well.

As for the import confusion: it's a bit of a legacy thing. Importing datetime from datetime is indeed confusing. The first datetime in from datetime import datetime is the module, the second one is a class with useful class methods (these are the functions you often want).

It's probably best to always from datetime import datetime, and import other parts as well if you need them like from datetime import datetime, timedelta. Or have multiple import statements, if you prefer.

The reason I picked 2,147,483,647 seemingly at random is that this is the maximum integer value for a 32-bit integer and epoch time is not normally defined beyond it. More here: https://en.wikipedia.org/wiki/Year_2038_problem

Of course, different solutions to the Year 2038 problem may cause the code above to become a problem, which is why I would recommend representing epoch time in your code to always mean 'milliseconds since 1970-01-01 00:00:00' (with our without fractions), to avoid future issues.

Upvotes: 2

Related Questions