
is there a more detailed explanation of why mktime does binary search? ** Adapted from code provided by Robert Elz, who writes: ** The "best" way to do mktime I think is based on an idea of Bob ** Kridle's (so its said...) from a long time ago. ** It does a binary search of the time_t space. Since time_t's are ** just 32 bits, its a max of 32 iterations (even at 64 bits it ** would still be very reasonable). this came up on Android because we had some code that did "errno = 0; mktime(...); if (errno == EOVERFLOW) ..." rather than checking the return value of mktime. this failed for us because the tzcode mktime sets errno even on non-failure. obviously i can fix this by saving errno around the call to mktime_tzname in mktime, but i'm curious to know why there's a binary search at all. i also notice that, of the BSDs, NetBSD seems to have fixed this locally, FreeBSD has an old enough copy of tzcode that it's not setting errno at all, and OpenBSD is in the same boat as Android. here's the NetBSD change, which is does the errno save-restore in time1 instead: revision 1.90 date: 2014-10-16 10:53:32 -0700; author: christos; state: Exp; lines: +24 -36; commitid: 4woGqYWkKe0i6sUx; - don't leak errno in mktime() - when we load a new timezone, don't change anything unless the load succeeded. http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/time/localtime.c.diff?r1=1....

enh via tz <tz@iana.org> writes:
this came up on Android because we had some code that did "errno = 0; mktime(...); if (errno == EOVERFLOW) ..." rather than checking the return value of mktime. this failed for us because the tzcode mktime sets errno even on non-failure.
Separate from the question of whether binary search is a good idea... This is, in general, an error in C programming unless the C API specifically documents this error checking pattern (strtol is one of the few APIs that does). If you call a library function that is documented as setting errno, and it does not return an error, errno is undefined. glibc sets errno to various things on non-failure in many of its interfaces, so code that assumes errno will only be non-zero on failure is going to break a lot. -- Russ Allbery (eagle@eyrie.org) <http://www.eyrie.org/~eagle/>

Russ Allbery wrote:
If you call a library function that is documented as setting errno, and it does not return an error, errno is undefined.
Yes, and this is a glitch in mktime's API: if mktime succeeds and returns (time_t)-1, errno might still be set. Although mktime's caller can detect whether (time_t)-1 represents an error by passing (time_t)-1 to localtime_r and comparing the resulting struct tm to the one that mktime returned, this is annoying.

enh wrote:
is there a more detailed explanation of why mktime does binary search?
Russ Allbery answered the errno question, but as for the binary search: mktime is *really* *hard* to write, correctly, otherwise. Besides being considerably easier to implement, the binary search implementation effectively ensures that mktime is a perfect inverse of localtime, because it (literally) takes the localtime function and inverts it.
participants (4)
-
enh
-
Paul Eggert
-
Russ Allbery
-
scs@eskimo.com