On Thu, 30 Sep 2021, Riccardo (Jack) Lucchetti wrote:
On Thu, 30 Sep 2021, Sven Schreiber wrote:
> Am 30.09.2021 um 16:39 schrieb Riccardo (Jack) Lucchetti:
>> On Thu, 30 Sep 2021, Sven Schreiber wrote:
>>
>>> Then, I'm observing that the result for date_to_iso8601("1984",
"%Y")
>>> is: 19831231. Is this a bug? I would have expected 19840101.
>>
>> Indeed, this looks like a strptime bug. For example:
>
> So you mean gretl's strptime, or some other underlying library's strptime?
I mean gretl's implementation. Although this is weird, since our own
strpitime is basically just a wrapper around the corresponding C function. If
you want to take a look, the function you want is at line 8510 of
lib/src/geneval.c.
Here's the issue. strptime() gives you the time in the form of a
"struct tm", and strftime() wants a struct tm as input. But there's
nothing in hansl corresponding to struct tm, so we convert the
struct we get from strptime to calendar representation as a "time_t"
(basically, an integer) using the C-library function mktime(). Then
we convert back from time_t to struct tm if and when strftime is
called.
The trouble is that this round-trip goes wrong for an
underspecified time such as plain "1984". Given that input,
strptime leaves the "mday" (day-of-month) member of the tm struct
at 0, but that's not a valid value, mday has to be in the range 1 to
31. So mktime looks at the invalid 0th of January 1984 and
"corrects" it, as best it can, to the 31st of December 1983.
The fix is then to initialize mday to 1 before calling strptime. If
the input specifies a day of the month the "1" will get overwritten;
if it fails to supply a day of the month we default to the first.
That fix is now in git.
(This is kinda confusing: 0 is a valid value for all members of
struct tm -- for instance, internally January is month 0 -- except
for the day of the month.)
Allin