In MATLAB, I can easily convert a datetime object to posix:
start_time = datetime('2020-04-30 10:05:00');
start_time_unix = posixtime(start_time)
which returns:
start_time_unix = 1.588241100000000e+09.
In Python, I've created a similar datetime object and tried converting it to posix:
import time
import datetime
import numpy as np
time_string = '2020-04-30 10:05:00'
calendar, clock = time_string.split(' ')
year,month,day = [np.int(x) for x in calendar.split('-')]
hour,minute,second = [np.int(x) for x in clock.split(':')]
dt = datetime.datetime(year, month, day, hour, minute, second)
ut = time.mktime(dt.timetuple())
at which point,
ut = 1588262700.0
In case the hours and minutes are mixed up,
dt2 = datetime.datetime(year, month, day, minute, hour, second)
ut2 = time.mktime(dt2.timetuple())
returns
ut2 = 1588245000.0
Why am I seeing this discrepancy between MATLAB and Python? Also, is there a way to parse a date/time string and convert it to posix more efficiently?
In Python, if you parse a date/time string that does not contain timezone information or UTC offset to a datetime
object, the resulting object is naive, i.e. it does not know about any timezone, DST or UTC offset.
From the docs:
A naive object does not contain enough information to unambiguously locate itself relative to other date/time objects. Whether a naive object represents Coordinated Universal Time (UTC), local time, or time in some other timezone is purely up to the program, just like it is up to the program whether a particular number represents metres, miles, or mass. Naive objects are easy to understand and to work with, at the cost of ignoring some aspects of reality.
Python will by default assume that a naive datetime
object belongs in the timezone of your operating system!
More from the docs:
Warning: Because naive datetime objects are treated by many datetime methods as local times, it is preferred to use aware datetimes to represent times in UTC.
For the given example, you will need to specify timezone information to avoid ambiguities:
from datetime import datetime, timezone
# parse to datetime, in this case we don't need strptime since string is ISO8601 compatible
dtobj = datetime.fromisoformat('2020-04-30 10:05:00')
# naive, no tz info: datetime.datetime(2020, 4, 30, 10, 5)
# add a timezone, for UTC, we can use timezone.utc from the datetime module:
dtobj = dtobj.replace(tzinfo=timezone.utc)
# tz-aware: datetime.datetime(2020, 4, 30, 10, 5, tzinfo=datetime.timezone.utc)
# now we can obtain the posix timestamp:
posix = dtobj.timestamp()
print(posix)
# 1588241100.0
If you intend to work frequently with time series data in Python, have a look at the dateutil package.