Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Tue, 26 Mar 2024 12:45:46 +0000
From: Alexander Weps <>
Subject: Re: Broken mktime calculations when crossing DST boundary

See below.


On Tuesday, March 26th, 2024 at 00:34, Thorsten Glaser <> wrote:

> Alexander Weps dixit:
> > And all of this works in glibc.
> Not at all, glibc’s mktime just throws the towel with
> EOVERFLOW saying that the requested time does not exist.

How is this not compliant with POSIX?

This is perfectly valid behavior, that is both expected and can be handled in code easily.

I have to ask, but have you actually used mktime from the application end?

> (It is only not permitted to change the input struct tm
> member tm_wday if it returns EOVERFLOW but that doesn’t
> mean that the output struct tm is correct.)

I am not sure what you mean by correct. Struct tm is neither correct nor incorrect. It can be in three states:
1) Set by user.
2) Normalized by mktime.
3) Not fully normalized by mktime.

If I get -1, I know the struct tm does not represent valid time_t and I handle it and move on.

This is perfect example (TZ=Pacific/Apia):

before: 2011-12-31 00:00:00 +14 0
after1: 2011-12-31 00:00:00 +14 1325239200
after1: 2011-12-30 00:00:00 +14 -1
after1: 2011-12-29 00:00:00 -10 1325152800
after2: 2011-12-28 00:00:00 -10 1325066400
after2: 2011-12-29 00:00:00 -10 1325152800
after2: 2011-12-30 00:00:00 -10 -1
after3: 2011-12-31 00:00:00 +14 1325239200

I am enumerating midnighta of each day. If I get -1, I ignore that date and move along.

Musl instead of giving sane results starts running in the circle at some point:
after2: 2011-12-29 00:00:00 -10 1325152800
after3: 2011-12-29 00:00:00 -10 1325152800

> > > That’s because your application violates the constraints
> > > that bind both, not just the libc, to the spec.
> >
> > Specify those constraints.
> My wording here was badly, as dalias mentioned:
> > It's not a constraint violation. mktime is required to accept inputs
> > where the fields of the broken-down time don't fall within their
> > respective ranges, and normalize them.
> >
> > Rather, the calling code is just making incorrect assumptions about
> > the unspecified way that happens, […]
> The “constraint” (wrong word) I meant was that your program
> must not make assumptions about which of the two possible
> conflict resolutions the libc chooses.
> > Show me a function implementation that produces same time next day
> > under this behavior you assume to be correct.
> It is not possible to do that with mktime. You’ll have to do
> that yourself. POSIX even says so.
> It does indicate that on implementations (their word for libcs
> here) that follow its recommendation to not normalise tm_sec,
> you can achieve the desired effect by adding 86400 to it, though
> that will not work right in the presence of a leap second on
> systems honouring them (which is a deviation from POSIX, of
> course).
> Adding 86400 to the time_t value, under the same leap second
> caveat, can work if your code can rely on POSIX (ISO C does not
> specify the internal structure of time_t).
> bye,
> //mirabilos
> --
> 22:20⎜<asarch> The crazy that persists in his craziness becomes a master
> 22:21⎜<asarch> And the distance between the craziness and geniality is
> only measured by the success 18:35⎜<asarch> "Psychotics are consistently
> inconsistent. The essence of sanity is to be inconsistently inconsistent

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.