3

I know these questions have been asked before but I'm struggling to convert a timestamp string to a unix time and figuring out whether the datetime objects are naive or aware

For example, to convert the time "2021-05-19 12:51:47" to unix:

>>> from datetime import datetime as dt
>>> dt_obj = dt.strptime("2021-05-19 12:51:47", "%Y-%m-%d %H:%M:%S")
>>> dt_obj
datetime.datetime(2021, 5, 19, 12, 51, 47)

is dt_obj naive or aware and how would you determine this? The methods on dt_obj such as timetz, tzinfo, and tzname don't seem to indicate anything - does that mean that dt_obj is naive?

Then to get unix:

>>> dt_obj.timestamp()
1621421507.0

However when I check 1621421507.0 on say https://www.unixtimestamp.com then it tells me that gmt for the above is Wed May 19 2021 10:51:47 GMT+0000, ie 2 hours behind the original timestamp?

3 Answers 3

2

since Python's datetime treats naive datetime as local time by default, you need to set the time zone (tzinfo attribute):

from datetime import datetime, timezone

# assuming "2021-05-19 12:51:47" represents UTC:
dt_obj = datetime.fromisoformat("2021-05-19 12:51:47").replace(tzinfo=timezone.utc)

Or, as @Wolf suggested, instead of setting the tzinfo attribute explicitly, you can also modify the input string by adding "+00:00" which is parsed to UTC;

dt_obj = datetime.fromisoformat("2021-05-19 12:51:47" + "+00:00")

In any case, the result

dt_obj.timestamp()
# 1621428707.0

now converts as expected on https://www.unixtimestamp.com/: enter image description here

Sign up to request clarification or add additional context in comments.

6 Comments

What speaks against datetime.fromisoformat("2021-05-19 12:51:47 +00:00")?
Thank you so much and noted on datetime.fromisoformat
@Wolf: I've added your suggestion to the answer, thanks for the comment! I was a bit reluctant to the string modification but it's clearly more efficient than using replace.
@uroboros: glad I could help! also take note of Wolf's suggestion; it's more efficient if you have a lot of data to process.
@Wolf regarding "Isn't this biased within one hour in a year": you mean because of a DST transition? - No I don't think so, assuming the input string represents UTC. If it would represent local time, then yes. You'd have to set the local time zone first and then convert to UTC (and then take timestamp if needed).
|
2

As long as you don't specify the timezone when calling strptime, you will produce naive datetime objects. You may pass time zone information via %z format specifier and +00:00 added to the textual date-time representation to get a timezone aware datetime object:

from datetime import datetime

dt_str = "2021-05-19 12:51:47"
print(dt_str)
dt_obj = datetime.strptime(dt_str+"+00:00", "%Y-%m-%d %H:%M:%S%z")
print(dt_obj)
print(dt_obj.timestamp())

The of above script is this:

2021-05-19 12:51:47
2021-05-19 12:51:47+00:00
1621428707.0

1 Comment

speaking of efficiency, note: A faster strptime
1

datetime.timestamp()

Naive datetime instances are assumed to represent local time and this method relies on the platform C mktime() function to perform the conversion.

So using this does automatically apply yours machine current timezone, following recipe is given to calculate timestamp from naive datetime without influence of timezone:

timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)

1 Comment

although this is also suggested elsewhere, I think it is hard to read and only works because datetime(1970, 1, 1) is also treated as local time. To me, this seems like "right for the wrong reason".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.