[Bug 280922] Change 46c599340f187db577b9212ab18022f3c7380c68 fixes one case (localtime / gmtime -> strftime('%s'), but breaks another

From: <bugzilla-noreply_at_freebsd.org>
Date: Mon, 19 Aug 2024 14:35:45 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=280922

--- Comment #3 from Vladislav Shabanov <vlad.shabanov@gmail.com> ---
(In reply to Dag-Erling Smørgrav from comment #2)
Thank you for reply.

First of all, the current implementation of libc will produce completely wrong
result when someone initializes only standard fields:
  struct tm x;
  x.tm_hour = 1;
  x.tm_min = 2;
  x.tm_sec = 3;
  x.tm_mday = 4;
  x.tm_mon = 6;
  x.tm_year = 106;
  x.tm_isdst = -1;
  strftime(....)


This is because tm_gmtoff can get any value. In my first test, I got ~10 years
shift just because follow the C reference.

That's why most portable code does some equivalent of bzero(&x), including
Python. Python, like many other big codebases, is tolerant to added, but unused
fields.
Certainly, Python does bzero.

Secondly, there is no way change Python to adopt it to new behaviour of
strftime: the time and timetouple API is standard, nobody will add extra fields
to it, because it will break a lot of Python code. Furthermore, it's impossible
to fix the problem at Python level (restore  tm_gmtoff), because it lost
earlier, when datetime is converted to timetouple. 

To sum up, now we have implementation with two problems:
1) it gives absolutely wrong result with badly written program initializing
only  documented fields (I mean, in POSIX standard) and leaves tm_gmtoff
initialized. I sure that there are a lot of code written in last 50 years doing
so.
2) It changes assumption that the unpacked struct tm is treated as local time,
which is mentioned in manual, and gives unexpected result when someone
construct struct tm manually without the knowledge of tm_gmtoff.

The proposed patch solves only the second problem. Maybe, it makes sence to
change
(t->tm_gmtoff || t->tm_zone)  to (t->tm_gmtoff && t->tm_zone) to fix both
cases.

Anyway, this patch keeps your original problem solved, because gmtime and
localtime fills both tm_gmtoff and tm_zone and new behaviour breaks less
existing code.

-- 
You are receiving this mail because:
You are the assignee for the bug.