EDIT2: This question is assuming a POSIX-ish platform with Python linked against Glibc.
On my system, round-trip conversion using the %z
formatting directive
using Python’s time library fails to parse the offset part of ISO 8601
formatted timestamps. This snippet:
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)
outputs:
»»»» False False
»»»» GMT 2018-02-16T09:26:34Z+0000
»»»» None 2018-02-16T09:26:34Z
whereas the expected output would be
»»»» True True
»»»» GMT 2018-02-16T09:26:34Z+0000
»»»» GMT 2018-02-16T09:26:34Z+0000
How do I get %z
to respect that offset?
- Python 3.3.2 and 3.6.4
- [Glibc 2.17 and 2.25 ⇒ see below!]
EDIT: Glibc can be acquitted as proven by this C analogue:
#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);
}
Which outputs
»»»» b ?= d yep
»»»» 0 <GMT> 2018-02-16T10:28:18Z+0000
»»»» 0 <(null)> 2018-02-16T10:28:18Z+0000