From bf2e078ecf88746ee4e2a739185fc20d2d932654 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 8 Jun 2026 21:19:52 +0000 Subject: [PATCH] Add a relative time option for time formatting, GitHub issue 5009. --- format.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- tmux.1 | 10 ++++++++-- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/format.c b/format.c index 7b184613..15afbe0b 100644 --- a/format.c +++ b/format.c @@ -117,6 +117,7 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2) #define FORMAT_NOT_NOT 0x100000 #define FORMAT_REPEAT 0x200000 #define FORMAT_QUOTE_ARGUMENTS 0x400000 +#define FORMAT_RELATIVE 0x800000 /* Limit on recursion. */ #define FORMAT_LOOP_LIMIT 100 @@ -4045,6 +4046,50 @@ format_pretty_time(time_t t, int seconds) return (xstrdup(s)); } +/* Make a relative time. */ +static char * +format_relative_time(time_t t) +{ + time_t now, age; + u_int d, h, m, s; + char out[32], sign; + + time(&now); + if (t == now) + return (xstrdup("0s")); + if (t > now) { + sign = '+'; + age = t - now; + } else { + sign = '-'; + age = now - t; + } + + d = age / 86400; + h = (age % 86400) / 3600; + m = (age % 3600) / 60; + s = age % 60; + + if (d != 0) { + if (h != 0) + xsnprintf(out, sizeof out, "%c%ud%uh", sign, d, h); + else + xsnprintf(out, sizeof out, "%c%ud", sign, d); + } else if (h != 0) { + if (m != 0) + xsnprintf(out, sizeof out, "%c%uh%um", sign, h, m); + else + xsnprintf(out, sizeof out, "%c%uh", sign, h); + } else if (m != 0) { + if (s != 0) + xsnprintf(out, sizeof out, "%c%um%us", sign, m, s); + else + xsnprintf(out, sizeof out, "%c%um", sign, m); + } else + xsnprintf(out, sizeof out, "%c%us", sign, s); + return (xstrdup(out)); +} + /* Find a format entry. */ static char * format_find(struct format_tree *ft, const char *key, int modifiers, @@ -4126,7 +4171,9 @@ found: } if (t == 0) return (NULL); - if (modifiers & FORMAT_PRETTY) + if (modifiers & FORMAT_RELATIVE) + found = format_relative_time(t); + else if (modifiers & FORMAT_PRETTY) found = format_pretty_time(t, 0); else { if (time_format != NULL) { @@ -5131,6 +5178,8 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen, break; if (strchr(fm->argv[0], 'p') != NULL) modifiers |= FORMAT_PRETTY; + else if (strchr(fm->argv[0], 'r') != NULL) + modifiers |= FORMAT_RELATIVE; else if (fm->argc >= 2 && strchr(fm->argv[0], 'f') != NULL) { free(time_format); diff --git a/tmux.1 b/tmux.1 index 130b8cf3..57746ac7 100644 --- a/tmux.1 +++ b/tmux.1 @@ -6323,9 +6323,15 @@ gives gives .Ql Sun Oct 25 09:25:02 2015 . Adding -.Ql p ( -.Ql `t/p` ) +.Ql p +.Pq Ql t/p will use shorter but less accurate time format for times in the past. +.Ql r +.Pq Ql t/r +will show the time relative to the current time, for example +.Ql \-1m +or +.Ql +2m23s . A custom format may be given using an .Ql f suffix (note that