Whats wrong with my datetime.strptime format?

﹥>﹥吖頭↗ 提交于 2019-12-17 21:14:02

问题


With this function:

timestamp = datetime.strptime(date_str, date_fmt)

I am getting this error:

ValueError: time data 'Sun, 28 Oct 2018 07:33:13 -0400 (EDT)' does not match format '%a, %d %b %Y %H:%M:%S %z (%Z)'

Sun, 28 Oct 2018 07:33:13 -0400 (EDT)
%a, %d %b %Y %H:%M:%S %z (%Z)

I've looked over it a dozen times and I can't figure out what I am doing wrong.

My Python Version:

Python 3.7.0 (default, Jul 23 2018, 20:24:19) 

回答1:


There is no support for %Z on input for anything other than your current timezone. Only the strings in the time.tzname tuple plus 'UTC' and 'GMT' will ever be recognised:

>>> from datetime import datetime
>>> import time
>>> time.tzname
('GMT', 'BST')
>>> sample = 'Sun, 28 Oct 2018 07:33:13 -0400 (EDT)'
>>> datetime.strptime(sample.replace('EDT', time.tzname[0]), '%a, %d %b %Y %H:%M:%S %z (%Z)')
datetime.datetime(2018, 10, 28, 7, 33, 13, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000), 'GMT'))
>>> datetime.strptime(sample.replace('EDT', time.tzname[1]), '%a, %d %b %Y %H:%M:%S %z (%Z)')
datetime.datetime(2018, 10, 28, 7, 33, 13, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000), 'BST'))

Even if you use a 'known' timezone name in your input, the name is ignored unless there is also an timezone offset (%z) in the input; with a %z offset it is used only to set the name argument of the datetime.timezone() instance that's constructed from the %z offset.

This behaviour is, unfortunately, not clearly documented, see Python issues #22377 and #22426. The documentation may seem to imply that EST would be an acceptable value for %Z to parse, but that section of the documentation only shows datetime.strftime() string outputs, not acceptable datetime.strptime() string inputs.

Since you also have the offset from UTC in the string (the -0400 part), just remove the timezone name from your input and don't bother trying to parse it:

>>> datetime.strptime(sample.rpartition(' ')[0], '%a, %d %b %Y %H:%M:%S %z')
datetime.datetime(2018, 10, 28, 7, 33, 13, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000)))

I used str.rpartition() here to remove everything starting at the last space, but it depends on what kind of inputs that you have how to best remove the timezone name part in your application. Without it, the (%Z) section is not needed and you get a correct datetime object.

When debugging datetime.strptime() issues, you want to compartmentalise the issue. You can bisect the input and template parts to see where the issue lies, or try out the different components one by one. It could be a single directive that causes the issue, or multiple, so I usually go for single-step removing of directives until one works.


For those interested in the nitty gritty details of how datetime.strptime() works, you can step into the call with a debugger as the implementation uses a pure Python module. For datetime.strptime(), the entry point is _strptime._strptime_datetime(), and the %Z parameter matching pattern is generated by this little loop, where self.locale_time.timezone is a 2-value tuple of frozensets with 3-letter strings, which was set by the LocaleTime.__calc_timezone() method.



来源:https://stackoverflow.com/questions/53033221/whats-wrong-with-my-datetime-strptime-format

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!