• Tom Lane's avatar
    Work around portability issue with newer versions of mktime(). · f807e341
    Tom Lane authored
    Recent glibc versions have made mktime() fail if tm_isdst is
    inconsistent with the prevailing timezone; in particular it fails for
    tm_isdst = 1 when the zone is UTC.  (This seems wildly inconsistent
    with the POSIX-mandated treatment of "incorrect" values for the other
    fields of struct tm, so if you ask me it's a bug, but I bet they'll
    say it's intentional.)  This has been observed to cause cosmetic
    problems when pg_restore'ing an archive created in a different
    timezone.
    
    To fix, do mktime() using the field values from the archive, and if
    that fails try again with tm_isdst = -1.  This will give a result
    that's off by the UTC-offset difference from the original zone, but
    that was true before, too.  It's not terribly critical since we don't
    do anything with the result except possibly print it.  (Someday we
    should flush this entire bit of logic and record a standard-format
    timestamp in the archive instead.  That's not okay for a back-patched
    bug fix, though.)
    
    Also, guard our only other use of mktime() by having initdb's
    build_time_t() set tm_isdst = -1 not 0.  This case could only have
    an issue in zones that are DST year-round; but I think some do exist,
    or could in future.
    
    Per report from Wells Oliver.  Back-patch to all supported
    versions, since any of them might need to run with a newer glibc.
    
    Discussion: https://postgr.es/m/CAOC+FBWDhDHO7G-i1_n_hjRzCnUeFO+H-Czi1y10mFhRWpBrew@mail.gmail.com
    f807e341
findtimezone.c 44 KB