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
maint
Junio C Hamano 2021-12-10 14:35:07 -08:00
commit 1c39c822a9
5 changed files with 20 additions and 3 deletions

View File

@ -1047,7 +1047,7 @@ omitted.
has no effect. has no effect.


`--date=format:...` feeds the format `...` to your system `strftime`, `--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 Use `--date=format:%c` to show the date in your system locale's
preferred format. See the `strftime` manual for a complete list of preferred format. See the `strftime` manual for a complete list of
format placeholders. When using `-local`, the correct syntax is format placeholders. When using `-local`, the correct syntax is

View File

@ -1588,6 +1588,7 @@ timestamp_t approxidate_careful(const char *, int *);
timestamp_t approxidate_relative(const char *date); timestamp_t approxidate_relative(const char *date);
void parse_date_format(const char *format, struct date_mode *mode); void parse_date_format(const char *format, struct date_mode *mode);
int date_overflows(timestamp_t date); int date_overflows(timestamp_t date);
time_t tm_to_time_t(const struct tm *tm);


#define IDENT_STRICT 1 #define IDENT_STRICT 1
#define IDENT_NO_DATE 2 #define IDENT_NO_DATE 2

2
date.c
View File

@ -9,7 +9,7 @@
/* /*
* This is like mktime, but without normalization of tm_wday and tm_yday. * 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[] = { static const int mdays[] = {
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334

View File

@ -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 * 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 (;;) { for (;;) {
const char *percent = strchrnul(fmt, '%'); 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, "%%"); strbuf_addstr(&munged_fmt, "%%");
fmt++; fmt++;
break; 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': case 'z':
strbuf_addf(&munged_fmt, "%+05d", tz_offset); strbuf_addf(&munged_fmt, "%+05d", tz_offset);
fmt++; fmt++;

View File

@ -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:%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-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 # arbitrary time absurdly far in the future
FUTURE="5758122296 -0400" FUTURE="5758122296 -0400"
check_show iso "$FUTURE" "2152-06-19 18:24:56 -0400" TIME_IS_64BIT,TIME_T_IS_64BIT check_show iso "$FUTURE" "2152-06-19 18:24:56 -0400" TIME_IS_64BIT,TIME_T_IS_64BIT