Skip to content

Commit 5633c4f

Browse files
authored
bpo-34672: Try to pass the C library's own timezone strings back to it. (GH-9288)
1 parent a4414ef commit 5633c4f

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add a workaround, so the ``'Z'`` :func:`time.strftime` specifier on the musl
2+
C library can work in some cases.

Modules/timemodule.c

+36-4
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,10 @@ time_localtime(PyObject *self, PyObject *args)
523523
#endif
524524
}
525525

526+
#if defined(__linux__) && !defined(__GLIBC__)
527+
static const char *utc_string = NULL;
528+
#endif
529+
526530
PyDoc_STRVAR(localtime_doc,
527531
"localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n\
528532
tm_sec,tm_wday,tm_yday,tm_isdst)\n\
@@ -565,11 +569,32 @@ gettmarg(PyObject *args, struct tm *p, const char *format)
565569
if (Py_TYPE(args) == &StructTimeType) {
566570
PyObject *item;
567571
item = PyTuple_GET_ITEM(args, 9);
568-
p->tm_zone = item == Py_None ? NULL : (char*)PyUnicode_AsUTF8(item);
572+
if (item != Py_None) {
573+
p->tm_zone = PyUnicode_AsUTF8(item);
574+
if (p->tm_zone == NULL) {
575+
return 0;
576+
}
577+
#if defined(__linux__) && !defined(__GLIBC__)
578+
// Make an attempt to return the C library's own timezone strings to
579+
// it. musl refuses to process a tm_zone field unless it produced
580+
// it. See issue #34672.
581+
if (utc_string && strcmp(p->tm_zone, utc_string) == 0) {
582+
p->tm_zone = utc_string;
583+
}
584+
else if (tzname[0] && strcmp(p->tm_zone, tzname[0]) == 0) {
585+
p->tm_zone = tzname[0];
586+
}
587+
else if (tzname[1] && strcmp(p->tm_zone, tzname[1]) == 0) {
588+
p->tm_zone = tzname[1];
589+
}
590+
#endif
591+
}
569592
item = PyTuple_GET_ITEM(args, 10);
570-
p->tm_gmtoff = item == Py_None ? 0 : PyLong_AsLong(item);
571-
if (PyErr_Occurred())
572-
return 0;
593+
if (item != Py_None) {
594+
p->tm_gmtoff = PyLong_AsLong(item);
595+
if (PyErr_Occurred())
596+
return 0;
597+
}
573598
}
574599
#endif /* HAVE_STRUCT_TM_TM_ZONE */
575600
return 1;
@@ -1736,6 +1761,13 @@ PyInit_time(void)
17361761
PyModule_AddIntConstant(m, "_STRUCT_TM_ITEMS", 11);
17371762
PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType);
17381763
initialized = 1;
1764+
1765+
#if defined(__linux__) && !defined(__GLIBC__)
1766+
struct tm tm;
1767+
if (gmtime_r(0, &tm) != NULL)
1768+
utc_string = tm.tm_zone;
1769+
#endif
1770+
17391771
return m;
17401772
}
17411773

0 commit comments

Comments
 (0)