summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2021-12-10 14:35:07 -0800
committerLibravatar Junio C Hamano <gitster@pobox.com>2021-12-10 14:35:07 -0800
commit1c39c822a9a57efc811793ca0ffe9d872eabc12c (patch)
tree0116f2c7d3363f8f96634e185d90b67637b2524d
parentMerge branch 'js/ci-no-directional-formatting' (diff)
parentstrbuf_addftime(): handle "%s" manually (diff)
downloadtgif-1c39c822a9a57efc811793ca0ffe9d872eabc12c.tar.xz
Merge branch 'jk/strbuf-addftime-seconds-since-epoch'
The "--date=format:<strftime>" gained a workaround for the lack of system support for a non-local timezone to handle "%s" placeholder. * jk/strbuf-addftime-seconds-since-epoch: strbuf_addftime(): handle "%s" manually
-rw-r--r--Documentation/rev-list-options.txt2
-rw-r--r--cache.h1
-rw-r--r--date.c2
-rw-r--r--strbuf.c14
-rwxr-xr-xt/t0006-date.sh4
5 files changed, 20 insertions, 3 deletions
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 24569b06d1..43a86fa562 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -1047,7 +1047,7 @@ omitted.
has no effect.
`--date=format:...` feeds the format `...` to your system `strftime`,
-except for %z and %Z, which are handled internally.
+except for %s, %z, and %Z, which are handled internally.
Use `--date=format:%c` to show the date in your system locale's
preferred format. See the `strftime` manual for a complete list of
format placeholders. When using `-local`, the correct syntax is
diff --git a/cache.h b/cache.h
index eba12487b9..aa6f380d10 100644
--- a/cache.h
+++ b/cache.h
@@ -1588,6 +1588,7 @@ timestamp_t approxidate_careful(const char *, int *);
timestamp_t approxidate_relative(const char *date);
void parse_date_format(const char *format, struct date_mode *mode);
int date_overflows(timestamp_t date);
+time_t tm_to_time_t(const struct tm *tm);
#define IDENT_STRICT 1
#define IDENT_NO_DATE 2
diff --git a/date.c b/date.c
index c55ea47e96..84bb4451c1 100644
--- a/date.c
+++ b/date.c
@@ -9,7 +9,7 @@
/*
* This is like mktime, but without normalization of tm_wday and tm_yday.
*/
-static time_t tm_to_time_t(const struct tm *tm)
+time_t tm_to_time_t(const struct tm *tm)
{
static const int mdays[] = {
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
diff --git a/strbuf.c b/strbuf.c
index b22e981655..613fee8c82 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -1006,7 +1006,12 @@ void strbuf_addftime(struct strbuf *sb, const char *fmt, const struct tm *tm,
/*
* There is no portable way to pass timezone information to
- * strftime, so we handle %z and %Z here.
+ * strftime, so we handle %z and %Z here. Likewise '%s', because
+ * going back to an epoch time requires knowing the zone.
+ *
+ * Note that tz_offset is in the "[-+]HHMM" decimal form; this is what
+ * we want for %z, but the computation for %s has to convert to number
+ * of seconds.
*/
for (;;) {
const char *percent = strchrnul(fmt, '%');
@@ -1019,6 +1024,13 @@ void strbuf_addftime(struct strbuf *sb, const char *fmt, const struct tm *tm,
strbuf_addstr(&munged_fmt, "%%");
fmt++;
break;
+ case 's':
+ strbuf_addf(&munged_fmt, "%"PRItime,
+ (timestamp_t)tm_to_time_t(tm) -
+ 3600 * (tz_offset / 100) -
+ 60 * (tz_offset % 100));
+ fmt++;
+ break;
case 'z':
strbuf_addf(&munged_fmt, "%+05d", tz_offset);
fmt++;
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 6b757d7169..794186961e 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -63,6 +63,10 @@ check_show 'format-local:%%z' "$TIME" '%z'
check_show 'format:%Y-%m-%d %H:%M:%S' "$TIME" '2016-06-15 16:13:20'
check_show 'format-local:%Y-%m-%d %H:%M:%S' "$TIME" '2016-06-15 09:13:20' '' EST5
+check_show 'format:%s' '123456789 +1234' 123456789
+check_show 'format:%s' '123456789 -1234' 123456789
+check_show 'format-local:%s' '123456789 -1234' 123456789
+
# arbitrary time absurdly far in the future
FUTURE="5758122296 -0400"
check_show iso "$FUTURE" "2152-06-19 18:24:56 -0400" TIME_IS_64BIT,TIME_T_IS_64BIT