python: convert pywintyptes.datetime to datetime.datetime

So the problem is the +00:00 timezone offset. Looking into this there's not an out of the box solution for Python

datetime.datetime.strptime("2016-04-01 17:29:25+00:00", '%Y-%m-%d %H:%M:%S %z')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/_strptime.py", line 324, in _strptime
    (bad_directive, format))
ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M:%S %z'

One band-aid solution is to strip the timezone but that feels pretty gross.

datetime.datetime.strptime("2016-04-01 17:29:25+00:00".rstrip("+00:00"), '%Y-%m-%d %H:%M:%S')
datetime.datetime(2016, 4, 1, 17, 29, 25)

Looking around it looks like (if you can use a third party library) dateutil solves this issue and is nicer to use then datetime.strptime.

On Commandline

pip install python-dateutil

code

>>> import dateutil.parser                                                      
>>> dateutil.parser.parse("2016-04-01 17:29:25+00:00")
datetime.datetime(2016, 4, 1, 17, 29, 25, tzinfo=tzutc())

Pandas has a similar solution using pd.Timestamp()

Insert the pywintype.datetime object as the argument and set unit='s' (for Seconds, or enter whatever unit the timestamp is in).

For a pandas Series:

def convert(time):

    return pd.Timestamp(time.timestamp(), unit = 's')


newSeries = oldSeries.apply(convert)

I think you were quite close with the datetime.datetime.fromtimestamp. Taking that approach all the way, you could transform your pywintypes.datetime object to a timestamp using its timestamp method. To be safe with time zones, also use the tzinfo attribute. See In [4]: below for the full syntax.

I just ran into the same issue when trying to make a pd.DataFrame out of a few rows of an Excel book. I kept getting this terrible Python has stopped working" dialog box.

In [1]: pywindt
Out[1]: pywintypes.datetime(2018, 9, 13, 14, 2, 24, tzinfo=TimeZoneInfo('GMT Standard Time', True))

In [2]: str(pywindt)
Out[2]: '2018-09-13 14:02:24+00:00'

In [3]: # Conversion takes place here!

In [4]: dt = datetime.datetime.fromtimestamp(
   ...:     timestamp=pywindt.timestamp(),
   ...:     tz=pywindt.tzinfo
   ...: )

In [5]: dt
Out[5]: datetime.datetime(2018, 9, 13, 14, 2, 24, tzinfo=TimeZoneInfo('GMT Standard Time', True))

In [6]: str(dt)
Out[6]: '2018-09-13 14:02:24+00:00'

As a follow up, if you need to check whether or not a cell value is a pywintypes datetime, the following should be good enough.

In [7]: import pywintypes

In [8]: isinstance(pywindt, pywintypes.TimeType)
Out[8]: True

In [9]: # just out of curiousity

In [10]: isinstance(dt, pywintypes.TimeType)
Out[10]: False