diff --git a/src/bin/initdb/findtimezone.c b/src/bin/initdb/findtimezone.c index 47c833fc81b..a087a764be5 100644 --- a/src/bin/initdb/findtimezone.c +++ b/src/bin/initdb/findtimezone.c @@ -195,6 +195,7 @@ build_time_t(int year, int month, int day) tm.tm_mday = day; tm.tm_mon = month - 1; tm.tm_year = year - 1900; + tm.tm_isdst = -1; return mktime(&tm); } diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index a67e110660f..df052a6c465 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -3615,7 +3615,6 @@ void ReadHead(ArchiveHandle *AH) { int fmt; - struct tm crtm; /* * If we haven't already read the header, do so. @@ -3683,6 +3682,8 @@ ReadHead(ArchiveHandle *AH) if (AH->version >= K_VERS_1_4) { + struct tm crtm; + crtm.tm_sec = ReadInt(AH); crtm.tm_min = ReadInt(AH); crtm.tm_hour = ReadInt(AH); @@ -3691,12 +3692,33 @@ ReadHead(ArchiveHandle *AH) crtm.tm_year = ReadInt(AH); crtm.tm_isdst = ReadInt(AH); - AH->archdbname = ReadStr(AH); - + /* + * Newer versions of glibc have mktime() report failure if tm_isdst is + * inconsistent with the prevailing timezone, e.g. tm_isdst = 1 when + * TZ=UTC. This is problematic when restoring an archive under a + * different timezone setting. If we get a failure, try again with + * tm_isdst set to -1 ("don't know"). + * + * XXX with or without this hack, we reconstruct createDate + * incorrectly when the prevailing timezone is different from + * pg_dump's. Next time we bump the archive version, we should flush + * this representation and store a plain seconds-since-the-Epoch + * timestamp instead. + */ AH->createDate = mktime(&crtm); - if (AH->createDate == (time_t) -1) - write_msg(modulename, "WARNING: invalid creation date in header\n"); + { + crtm.tm_isdst = -1; + AH->createDate = mktime(&crtm); + if (AH->createDate == (time_t) -1) + write_msg(modulename, + "WARNING: invalid creation date in header\n"); + } + } + + if (AH->version >= K_VERS_1_4) + { + AH->archdbname = ReadStr(AH); } if (AH->version >= K_VERS_1_10)