python: convert pywintyptes.datetime to datetime.d

2020-07-10 02:56发布

I am using pywin32 to read/write to an Excel file. I have some dates in Excel, stored in format yyyy-mm-dd hh:mm:ss. I would like to import those into Python as datetime.datetime objects. Here is the line of code I started with:

prior_datetime = datetime.strptime(excel_ws.Cells(2, 4).Value, '%Y-%m-%d %H:%M:%S')

That didn't work. I got the error:

strptime() argument 1 must be str, not pywintypes.datetime

I tried casting it to a string, like so:

prior_datetime = datetime.strptime(str(excel_ws.Cells(2, 4).Value), '%Y-%m-%d %H:%M:%S')

That didn't work either. I got the error:

ValueError: unconverted data remains: +00:00

So then I tried something a little different:

prior_datetime = datetime.fromtimestamp(int(excel_ws.Cells(2, 4).Value))

Still no luck. Error:

TypeError: a float is required.

Casting to a float didn't help. Nor integer. (Hey, I was desperate at this point.)

I might be looking in the wrong plce, but I'm having a terrible time finding any good documentation on pywin32 in general or pywintypes or pywintypes.datetime in particular.

Any help?

5条回答
劳资没心,怎么记你
2楼-- · 2020-07-10 03:26

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
查看更多
手持菜刀,她持情操
3楼-- · 2020-07-10 03:29

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())
查看更多
Animai°情兽
4楼-- · 2020-07-10 03:34

You can try something like this

prior_datetime = datetime.strptime((str(excel_ws.Cells(2, 4).Value)).rstrip("+00:00"), '%Y-%m-%d %H:%M:%S')
查看更多
太酷不给撩
5楼-- · 2020-07-10 03:38

Pandas has a similar solution using pd.Timestamp()

Just insert the pywintype.datetime object as the argument and set unit = whatever unit the time stamp is in (Seconds or 's' I think in this case).

For a pandas Series I did:

def convert(time):

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

And then:

newSeries = oldSeries.apply(convert)
查看更多
男人必须洒脱
6楼-- · 2020-07-10 03:42

Adding a simple option for converting pywintypes.datetime to datetime.datetime

By adding any datetime.datetime type to the pywintypes.datetime will result in a cast to the datetime.dateime type. This can be done using a zero-delta for example.

For the case of the original question, the below can be used without requiring additional modules

desired_datetime_type = excel_ws.Cells(2, 4).Value + datetime.timedelta(0)
查看更多
登录 后发表回答