diff --git a/src/backup.c b/src/backup.c index 420bcb78..4b9bb1ff 100644 --- a/src/backup.c +++ b/src/backup.c @@ -1836,7 +1836,7 @@ pg_stop_backup(pgBackup *backup) elog(ERROR, "result of txid_snapshot_xmax() is invalid: %s", PQgetvalue(res, 0, 0)); - if (!parse_time(PQgetvalue(res, 0, 1), &recovery_time)) + if (!parse_time(PQgetvalue(res, 0, 1), &recovery_time, true)) elog(ERROR, "result of current_timestamp is invalid: %s", PQgetvalue(res, 0, 1)); diff --git a/src/restore.c b/src/restore.c index a39b5127..80bbb8bc 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1036,7 +1036,7 @@ parseRecoveryTargetOptions(const char *target_time, rt->time_specified = true; rt->target_time_string = target_time; - if (parse_time(target_time, &dummy_time)) + if (parse_time(target_time, &dummy_time, false)) rt->recovery_target_time = dummy_time; else elog(ERROR, "Invalid value of --time option %s", target_time); diff --git a/src/util.c b/src/util.c index a43239dc..051f4d54 100644 --- a/src/util.c +++ b/src/util.c @@ -191,7 +191,7 @@ get_data_checksum_version(bool safe) /* - * Convert time_t value to ISO-8601 format string + * Convert time_t value to ISO-8601 format string. Always set timezone offset. */ void time2iso(char *buf, size_t len, time_t time) @@ -199,25 +199,23 @@ time2iso(char *buf, size_t len, time_t time) struct tm *ptm = gmtime(&time); time_t gmt = mktime(ptm); time_t offset; + char *ptr = buf; ptm = localtime(&time); offset = time - gmt + (ptm->tm_isdst ? 3600 : 0); - strftime(buf, len, "%Y-%m-%d %H:%M:%S", ptm); + strftime(ptr, len, "%Y-%m-%d %H:%M:%S", ptm); - if (offset != 0) + ptr += strlen(ptr); + snprintf(ptr, len - (ptr - buf), "%c%02d", + (offset >= 0) ? '+' : '-', + abs((int) offset) / SECS_PER_HOUR); + + if (abs((int) offset) % SECS_PER_HOUR != 0) { - buf += strlen(buf); - sprintf(buf, "%c%02d", - (offset >= 0) ? '+' : '-', - abs((int) offset) / SECS_PER_HOUR); - - if (abs((int) offset) % SECS_PER_HOUR != 0) - { - buf += strlen(buf); - sprintf(buf, ":%02d", - abs((int) offset % SECS_PER_HOUR) / SECS_PER_MINUTE); - } + ptr += strlen(ptr); + snprintf(ptr, len - (ptr - buf), ":%02d", + abs((int) offset % SECS_PER_HOUR) / SECS_PER_MINUTE); } } diff --git a/src/utils/pgut.c b/src/utils/pgut.c index f1b5babd..330f2fa5 100644 --- a/src/utils/pgut.c +++ b/src/utils/pgut.c @@ -256,7 +256,8 @@ assign_option(pgut_option *opt, const char *optarg, pgut_optsrc src) message = "a valid string. But provided: "; break; case 't': - if (parse_time(optarg, opt->var)) + if (parse_time(optarg, opt->var, + opt->source == SOURCE_FILE)) return; message = "a time"; break; @@ -746,9 +747,12 @@ parse_uint64(const char *value, uint64 *result, int flags) /* * Convert ISO-8601 format string to time_t value. + * + * If utc_default is true, then if timezone offset isn't specified tz will be + * +00:00. */ bool -parse_time(const char *value, time_t *result) +parse_time(const char *value, time_t *result, bool utc_default) { size_t len; int fields_num, @@ -870,7 +874,7 @@ parse_time(const char *value, time_t *result) *result = mktime(&tm); /* adjust time zone */ - if (tz_set) + if (tz_set || utc_default) { time_t ltime = time(NULL); struct tm *ptm = gmtime(<ime); diff --git a/src/utils/pgut.h b/src/utils/pgut.h index a27cea83..662f07c1 100644 --- a/src/utils/pgut.h +++ b/src/utils/pgut.h @@ -204,7 +204,7 @@ extern bool parse_int32(const char *value, int32 *result, int flags); extern bool parse_uint32(const char *value, uint32 *result, int flags); extern bool parse_int64(const char *value, int64 *result, int flags); extern bool parse_uint64(const char *value, uint64 *result, int flags); -extern bool parse_time(const char *value, time_t *result); +extern bool parse_time(const char *value, time_t *result, bool utc_default); extern bool parse_int(const char *value, int *result, int flags, const char **hintmsg);