diff --git a/src/bin/initdb/findtimezone.c b/src/bin/initdb/findtimezone.c index 45221378329..120ad8f0122 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 d9a028aa524..bcfe4fd0112 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -3723,7 +3723,6 @@ ReadHead(ArchiveHandle *AH) vmin, vrev; int fmt; - struct tm crtm; /* * If we haven't already read the header, do so. @@ -3791,6 +3790,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); @@ -3799,12 +3800,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)