【问题标题】:Python timezone '%z' directive for datetime.strptime() not availabledatetime.strptime() 的 Python 时区“%z”指令不可用
【发布时间】:2014-11-27 17:27:49
【问题描述】:

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

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

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

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

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]'

因为正如this bug report 所说

strftime() 按平台实现

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

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

我可以通过使用dateutil 模块将 GST 时间格式字符串转换为 tzinfo 对象 [如这里建议的那样][4] 来完美地做出以下解决方法 然后插入tzinfo into datetime object

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

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

[编辑]

好吧,看到 cmets 让我重新提出了我的问题,即如何使用 strptime() 解析电子邮件时区指示器而不知道语言环境时间?

【问题讨论】:

  • 如果 Python 所依赖的底层 C 库不支持它,你就不会得到它。
  • 所以我想我别无选择,每次都做这种丑陋且低效的解决方法?
  • 我不知道有什么方法可以做到这一点,而且我确信这个问题之前已经被问过了。
  • 对于时区的东西,你可能想看看pytz -> pytz.sourceforge.net

标签: python datetime tzinfo


【解决方案1】:

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

而不是使用:

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

使用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'))

【讨论】:

  • 不应该是 timedelta(hours=int(t[19:22]),minutes=int(t[23:])) ??
【解决方案2】:

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

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)

【讨论】:

    【解决方案3】:

    strptime() is implemented in pure Python。不像strftime();它[支持哪些指令]不依赖于平台。从 Python 3.2 开始支持 %z

    >>> 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)))
    

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

    Python 2.7 中没有具体的时区实现。您可以轻松实现 UTC 偏移量解析,请参阅How to parse dates with -0400 timezone string in python?

    【讨论】:

    • 注意%z 仅匹配 GMT、UTC 和 time.tzname。这是一个限制:bugs.python.org/issue22377
    • @xtreak 不要混淆 %Z(时区缩写)和 %z(数字偏移量)。
    • @jfs 感谢收看 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-22
    • 2013-06-14
    • 2019-08-29
    • 2022-06-21
    • 2020-02-20
    • 1970-01-01
    相关资源
    最近更新 更多