用于 datetime.strptime() 的 Python 时区“%z”指令不可用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26165659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 00:10:43  来源:igfitidea点击:

Python timezone '%z' directive for datetime.strptime() not available

pythondatetimetzinfo

提问by c24b

Using '%z' pattern of datetime.strptime()

使用 datetime.strptime() 的 '%z' 模式

I have a string text that represent a date and I'm perfectly able to parse it and transform it into a clean datetime object:

我有一个表示日期的字符串文本,我完全能够解析它并将其转换为一个干净的日期时间对象:

date = "[24/Aug/2014:17:57:26"
dt = datetime.strptime(date, "[%d/%b/%Y:%H:%M:%S")  

Except that I can't catch the entire date string with the timezoneusing the %z patternas specified here

除了我无法使用此处指定的%z 模式捕获带有时区的整个日期字符串

date_tz = 24/Aug/2014:17:57:26 +0200
dt = datetime.strptime(date, "[%d/%b/%Y:%H:%M:%S %z]")
>>> ValueError: 'z' is a bad directive in format '[%d/%b/%Y:%H:%M:%S %z]'

Because as this bug reportsays

因为正如这个错误报告所说

strftime() is implemented per platform

strftime()按平台实现

I precise that there is no such a problem with the naive tzinfo directive '%Z'

我确切地说,天真的 tzinfo 指令 '%Z' 没有这样的问题

Workaround : Casting tzinfo string into tzinfo object

解决方法:将 tzinfo 字符串转换为 tzinfo 对象

I can perfectly make the following workaround by transforming the GST time format string into a tzinfo object [as suggested here][4] using dateutilmodule and then insert tzinfo into datetime object

我可以通过使用dateutil模块将 GST 时间格式字符串转换为 tzinfo 对象 [如这里所建议的][4] ,然后将tzinfo插入到 datetime 对象中来完美地解决以下问题

Question: Make %z available for my plateform?

问题:让 %z 可用于我的平台?

But as I will obviously need %z pattern for further project I would like to find a solution to avoid this workaround and using external module for this simple task. Can you suggest me some reading on it? I supposed that newer version of python (I'm on 2.7) can handle it but I'd rather not changing my version now for this little but crucial detail.

但是因为我显然需要 %z 模式来进行进一步的项目,所以我想找到一种解决方案来避免这种变通方法并使用外部模块来完成这个简单的任务。你能给我推荐一些关于它的阅读吗?我认为较新版本的 python(我在 2.7 上)可以处理它,但我现在不想为了这个小而关键的细节而改变我的版本。

[EDIT]

[编辑]

Well, seeing comments make me reformulated my question how to parse Email time zone indicator using strptime() without being aware of locale time?

好吧,看到评论让我重新表述了我的问题如何在不知道区域设置时间的情况下使用 strptime() 解析电子邮件时区指示器?

采纳答案by jfs

strptime()is implemented in pure Python. Unlike strftime(); it [which directives are supported] doesn't depend on platform. %zis supported since Python 3.2:

strptime()是用纯 Python 实现的。不像strftime(); 它 [支持哪些指令] 不依赖于平台。%z自 Python 3.2 起支持:

>>> from datetime import datetime
>>> datetime.strptime('24/Aug/2014:17:57:26 +0200', '%d/%b/%Y:%H:%M:%S %z')
datetime.datetime(2014, 8, 24, 17, 57, 26, tzinfo=datetime.timezone(datetime.timedelta(0, 7200)))

how to parse Email time zone indicator using strptime() without being aware of locale time?

如何在不知道区域设置时间的情况下使用 strptime() 解析电子邮件时区指示器?

There is no concrete timezone implementation in Python 2.7. You could easily implement the UTC offset parsing, see How to parse dates with -0400 timezone string in python?

Python 2.7 中没有具体的时区实现。您可以轻松实现 UTC 偏移量解析,请参阅如何在 python 中使用 -0400 时区字符串解析日期?

回答by Uri Goren

In continue to @j-f-sebastians 's answer, here is a fix for python 2.7

继续@jf-sebastians 的回答,这里是 python 2.7 的修复

Instead of using:

而不是使用:

datetime.strptime(t,'%Y-%m-%dT%H:%M %z')

use the timedeltato account for the timezone, like this:

使用timedelta来说明时区,如下所示:

from datetime import datetime,timedelta
def dt_parse(t):
    ret = datetime.strptime(t[0:16],'%Y-%m-%dT%H:%M')
    if t[17]=='+':
       ret-=timedelta(hours=int(t[18:20]),minutes=int(t[20:]))
    elif t[17]=='-':
       ret+=timedelta(hours=int(t[18:20]),minutes=int(t[20:]))
    return ret

print(dt_parse('2017-01-12T14:12 -0530'))

回答by LaBE

The Answer of Uri is great, saved my life, but when you have USE_TZ = Trueyou need to be careful with the time, for avoid the warning "RuntimeWarning: DateTimeField" is better if you add the utc to the return.

Uri 的答案很棒,救了我的命,但是当你有 USE_TZ = True时间时,你需要小心时间,为了避免警告“RuntimeWarning:DateTimeField”,如果你将 utc 添加到返回中会更好。

import pytz
from datetime import datetime, timedelta
def dt_parse(t):
    ret = datetime.strptime(t[0:19],'%Y-%m-%dT%H:%M:%S')
    if t[23]=='+':
        ret-=timedelta(hours=int(t[24:26]), minutes=int(t[27:]))
    elif t[23]=='-':
        ret+=timedelta(hours=int(t[24:26]), minutes=int(t[27:]))
    return ret.replace(tzinfo=pytz.UTC)