首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python strptime‘’%z‘’

Python strptime‘’%z‘’
EN

Stack Overflow用户
提问于 2018-02-16 09:39:19
回答 2查看 1.5K关注 0票数 1

EDIT2:这个问题假设了一个POSIX平台,它与Glibc链接在一起。

在我的系统中,使用使用Python库的%z格式化指令的往返转换不能解析ISO8601格式化时间戳的偏移部分。这个片段:

代码语言:javascript
复制
import time
time.daylight = 0
fmt = "%Y-%m-%dT%H:%M:%SZ%z"
a=time.gmtime()
b=time.strftime(fmt, a)
c=time.strptime(b, fmt)
d=time.strftime(fmt, c)

print ("»»»»", a == c, b == d)
print ("»»»»", a.tm_zone, b)
print ("»»»»", c.tm_zone, d)

产出:

代码语言:javascript
复制
»»»» False False
»»»» GMT 2018-02-16T09:26:34Z+0000
»»»» None 2018-02-16T09:26:34Z

而预期的产出将是

代码语言:javascript
复制
»»»» True True
»»»» GMT 2018-02-16T09:26:34Z+0000
»»»» GMT 2018-02-16T09:26:34Z+0000

我如何让%z尊重这种抵消?

  • Python 3.3.2和3.6.4
  • Glibc 2.17和2.25⇒见下文!

编辑: Glibc可以被宣告无罪,这是通过这个C模拟:

代码语言:javascript
复制
#define _XOPEN_SOURCE
#define _DEFAULT_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* 2018-02-16T09:59:21Z+0000 */
#define ISO8601_FMT "%Y-%m-%dT%H:%M:%SZ%z"

int main () {
    const time_t t0 = time (NULL);
    struct tm a;
    char b [27];
    struct tm c;
    char d [27];

    (void)setenv ("TZ", "UTC", 1);
    tzset ();
    daylight = 0;

    (void)gmtime_r (&t0, &a);                       /* a=time.gmtime () */
    (void)strftime (b, sizeof(b), ISO8601_FMT, &a); /* b=time.strftime (fmt, a) */
    (void)strptime (b,            ISO8601_FMT, &c); /* c=time.strptime (b, fmt) */
    (void)strftime (d, sizeof(d), ISO8601_FMT, &c); /* d=time.strftime (fmt, c) */

    printf ("»»»» b ?= d %s\n",  strcmp (b, d) == 0 ? "yep" : "hell, no");
    printf ("»»»» %d <%s> %s\n", a.tm_isdst, a.tm_zone, b);
    printf ("»»»» %d <%s> %s\n", c.tm_isdst, c.tm_zone, d);
}

哪种输出

代码语言:javascript
复制
»»»» b ?= d yep
»»»» 0 <GMT> 2018-02-16T10:28:18Z+0000
»»»» 0 <(null)> 2018-02-16T10:28:18Z+0000
EN

回答 2

Stack Overflow用户

发布于 2018-02-16 09:51:22

对于"time.gmtime()“,您自然会得到UTC的时间,因此偏移量总是+0000,因此输出字符串"2018-02-16T09:26:34Z”对ISO8601是正确的。如果您绝对想要"+0000“,请手动添加它,因为它总是相同的:

代码语言:javascript
复制
d = time.strftime(fmt, c) + '+0000'
票数 2
EN

Stack Overflow用户

发布于 2018-02-16 10:01:18

我并不是假装有办法根据时区来产生适当的时差,但我可以解释这里发生了什么。

正如Python timezone '%z' directive for datetime.strptime() not available答案中所暗示的那样:

  • strptime是在纯python中实现的,因此它具有恒定的行为。
  • strftime依赖于它所链接的平台/C库。

在我的系统(WindowsPython3.4)上,%z返回与%Z (“巴黎,马德里”)相同的内容。因此,当strptime试图将其解析为数字时,它将失败。你的密码给了我:

代码语言:javascript
复制
ValueError: time data '2018-02-16T10:00:49ZParis, Madrid' does not match format '%Y-%m-%dT%H:%M:%SZ%z'

系统依赖于生成,而不是解析。

这种不对称解释了奇怪的行为。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48823828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档