git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 2/6] date: make "local" orthogonal to date format

From
John Keeping <john@keeping.me.uk>
Date
Sep 1, 2015, 21:55 UTC
Message-ID
<35b1313d4eb084ddc2bd70510d56e11a1d84e993.1441144343.git.john@keeping.me.uk>
In-Reply-To
<cover.1441144343.git.john@keeping.me.uk>
From: Jeff King <peff@peff.net>

Most of our "--date" modes are about the format of the date: which items we show and in what order. But "--date=local" is a bit of an oddball. It means "show the date in the normal format, but using the local timezone". The timezone we use is orthogonal to the actual format, and there is no reason we could not have "localized iso8601", etc.

This patch adds a "local" boolean field to "struct date_mode", and drops the DATE_LOCAL element from the date_mode_type enum (it's now just DATE_NORMAL plus local=1). The new feature is accessible to users by adding "-local" to any date mode (e.g., "iso-local"), and we retain "local" as an alias for "default-local" for backwards compatibility.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: John Keeping <john@keeping.me.uk>
---
This is Jeff's original patch with my fixup for DATE_STRFTIME squashed
in and a new change to reject "raw-local" (in both Documentation/ and
date.c).
 Documentation/rev-list-options.txt | 21 ++++++++---
 builtin/blame.c                    |  1 -
 cache.h                            |  2 +-
 date.c                             | 77 +++++++++++++++++++++++++-------------
 4 files changed, 67 insertions(+), 34 deletions(-)
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index a9b808f..5d28133 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -702,12 +702,16 @@ include::pretty-options.txt[]
 --date=(relative|local|default|iso|iso-strict|rfc|short|raw)::
 	Only takes effect for dates shown in human-readable format, such
 	as when using `--pretty`. `log.date` config variable sets a default
-	value for the log command's `--date` option.
+	value for the log command's `--date` option. By default, dates
+	are shown in the original time zone (either committer's or
+	author's). If `-local` is appended to the format (e.g.,
+	`iso-local`), the user's local time zone is used instead.
 +
 `--date=relative` shows dates relative to the current time,
-e.g. ``2 hours ago''.
+e.g. ``2 hours ago''. The `-local` option cannot be used with
+`--raw` or `--relative`.
 +
-`--date=local` shows timestamps in user's local time zone.
+`--date=local` is an alias for `--date=default-local`.
 +
 `--date=iso` (or `--date=iso8601`) shows timestamps in a ISO 8601-like format.
 The differences to the strict ISO 8601 format are:
@@ -730,10 +734,15 @@ format, often found in email messages.
 `--date=format:...` feeds the format `...` to your system `strftime`.
 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.
+format placeholders. When using `-local`, the correct syntax is
+`--date=format-local:...`.
 +
-`--date=default` shows timestamps in the original time zone
-(either committer's or author's).
+`--date=default` is the default format, and is similar to
+`--date=rfc2822`, with a few exceptions:
+
+	- there is no comma after the day-of-week
+
+	- the time zone is omitted when the local time zone is used
 
 ifdef::git-rev-list[]
 --header::
diff --git a/builtin/blame.c b/builtin/blame.c
index 4db01c1..6fd1a63 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -2600,7 +2600,6 @@ parse_done:
 		   fewer display columns. */
 		blame_date_width = utf8_strwidth(_("4 years, 11 months ago")) + 1; /* add the null */
 		break;
-	case DATE_LOCAL:
 	case DATE_NORMAL:
 		blame_date_width = sizeof("Thu Oct 19 16:00:04 2006 -0700");
 		break;
diff --git a/cache.h b/cache.h
index 4e25271..9a91b1d 100644
--- a/cache.h
+++ b/cache.h
@@ -1091,7 +1091,6 @@ struct date_mode {
 		DATE_NORMAL = 0,
 		DATE_RELATIVE,
 		DATE_SHORT,
-		DATE_LOCAL,
 		DATE_ISO8601,
 		DATE_ISO8601_STRICT,
 		DATE_RFC2822,
@@ -1099,6 +1098,7 @@ struct date_mode {
 		DATE_RAW
 	} type;
 	const char *strftime_fmt;
+	int local;
 };
 
 /*
diff --git a/date.c b/date.c
index 8f91569..f048416 100644
--- a/date.c
+++ b/date.c
@@ -166,6 +166,7 @@ struct date_mode *date_mode_from_type(enum date_mode_type type)
 	if (type == DATE_STRFTIME)
 		die("BUG: cannot create anonymous strftime date_mode struct");
 	mode.type = type;
+	mode.local = 0;
 	return &mode;
 }
 
@@ -189,7 +190,7 @@ const char *show_date(unsigned long time, int tz, const struct date_mode *mode)
 		return timebuf.buf;
 	}
 
-	if (mode->type == DATE_LOCAL)
+	if (mode->local)
 		tz = local_tzoffset(time);
 
 	tm = time_to_tm(time, tz);
@@ -232,7 +233,7 @@ const char *show_date(unsigned long time, int tz, const struct date_mode *mode)
 				tm->tm_mday,
 				tm->tm_hour, tm->tm_min, tm->tm_sec,
 				tm->tm_year + 1900,
-				(mode->type == DATE_LOCAL) ? 0 : ' ',
+				mode->local ? 0 : ' ',
 				tz);
 	return timebuf.buf;
 }
@@ -770,32 +771,56 @@ int parse_date(const char *date, struct strbuf *result)
 	return 0;
 }
 
+static enum date_mode_type parse_date_type(const char *format, const char **end)
+{
+	if (skip_prefix(format, "relative", end))
+		return DATE_RELATIVE;
+	if (skip_prefix(format, "iso8601-strict", end) ||
+	    skip_prefix(format, "iso-strict", end))
+		return DATE_ISO8601_STRICT;
+	if (skip_prefix(format, "iso8601", end) ||
+	    skip_prefix(format, "iso", end))
+		return DATE_ISO8601;
+	if (skip_prefix(format, "rfc2822", end) ||
+	    skip_prefix(format, "rfc", end))
+		return DATE_RFC2822;
+	if (skip_prefix(format, "short", end))
+		return DATE_SHORT;
+	if (skip_prefix(format, "default", end))
+		return DATE_NORMAL;
+	if (skip_prefix(format, "raw", end))
+		return DATE_RAW;
+	if (skip_prefix(format, "format", end))
+		return DATE_STRFTIME;
+
+	die("unknown date format %s", format);
+}
+
 void parse_date_format(const char *format, struct date_mode *mode)
 {
-	if (!strcmp(format, "relative"))
-		mode->type = DATE_RELATIVE;
-	else if (!strcmp(format, "iso8601") ||
-		 !strcmp(format, "iso"))
-		mode->type = DATE_ISO8601;
-	else if (!strcmp(format, "iso8601-strict") ||
-		 !strcmp(format, "iso-strict"))
-		mode->type = DATE_ISO8601_STRICT;
-	else if (!strcmp(format, "rfc2822") ||
-		 !strcmp(format, "rfc"))
-		mode->type = DATE_RFC2822;
-	else if (!strcmp(format, "short"))
-		mode->type = DATE_SHORT;
-	else if (!strcmp(format, "local"))
-		mode->type = DATE_LOCAL;
-	else if (!strcmp(format, "default"))
-		mode->type = DATE_NORMAL;
-	else if (!strcmp(format, "raw"))
-		mode->type = DATE_RAW;
-	else if (skip_prefix(format, "format:", &format)) {
-		mode->type = DATE_STRFTIME;
-		mode->strftime_fmt = xstrdup(format);
-	} else
-		die("unknown date format %s", format);
+	const char *p;
+
+	/* historical alias */
+	if (!strcmp(format, "local"))
+		format = "default-local";
+
+	mode->type = parse_date_type(format, &p);
+	mode->local = 0;
+
+	if (skip_prefix(p, "-local", &p)) {
+		if (mode->type == DATE_RELATIVE)
+			die("relative-local date format is nonsensical");
+		if (mode->type == DATE_RAW)
+			die("raw-local date format is nonsensical");
+		mode->local = 1;
+	}
+
+	if (mode->type == DATE_STRFTIME) {
+		if (!skip_prefix(p, ":", &p))
+			die("date format missing colon separator: %s", format);
+		mode->strftime_fmt = xstrdup(p);
+	} else if (*p)
+		die("unknown date-mode modifier: %s", p);
 }
 
 void datestamp(struct strbuf *out)
-- 
2.5.0.466.g9af26fa
Previous: John KeepingNext: Junio C Hamano
Message 16 of 59 in “date: allow any format to display local time”
  1. date: allow any format to display local timeJohn Keeping, Aug 30, 2015
  2. Junio C HamanoAug 31, 2015
  3. Jeff KingAug 31, 2015
  4. Jeff KingAug 31, 2015
  5. Junio C HamanoAug 31, 2015
  6. John KeepingAug 31, 2015
  7. Jeff KingAug 31, 2015
  8. 1/2 fast-import: switch crash-report date to iso8601Jeff King, Aug 31, 2015
  9. 2/2 date: make "local" orthogonal to date formatJeff King, Aug 31, 2015
  10. John KeepingAug 31, 2015
  11. Jeff KingAug 31, 2015
  12. Jeff KingAug 31, 2015
  13. John KeepingSep 1, 2015
  14. 0/6 Make "local" orthogonal to date formatJohn Keeping, Sep 1, 2015
  15. 1/6 fast-import: switch crash-report date to iso8601John Keeping, Sep 1, 2015
  16. 2/6 date: make "local" orthogonal to date formatJohn Keeping, Sep 1, 2015
  17. Junio C HamanoSep 1, 2015
  18. Jeff KingSep 1, 2015
  19. John KeepingSep 1, 2015
  20. Jeff KingSep 1, 2015
  21. Junio C HamanoSep 1, 2015
  22. Junio C HamanoSep 2, 2015
  23. 3/6 t6300: introduce test_date() helperJohn Keeping, Sep 1, 2015
  24. Junio C HamanoSep 1, 2015
  25. Eric SunshineSep 1, 2015
  26. Jeff KingSep 1, 2015
  27. John KeepingSep 1, 2015
  28. Jeff KingSep 1, 2015
  29. 4/6 t6300: make UTC and local dates differentJohn Keeping, Sep 1, 2015
  30. 5/6 t6300: add test for "raw" date formatJohn Keeping, Sep 1, 2015
  31. 6/6 t6300: add tests for "-local" date formatsJohn Keeping, Sep 1, 2015
  32. Jeff KingSep 1, 2015
  33. John KeepingSep 2, 2015
  34. Jeff KingSep 2, 2015
  35. Junio C HamanoSep 2, 2015
  36. John KeepingSep 2, 2015
  37. Junio C HamanoSep 2, 2015
  38. John KeepingSep 2, 2015
  39. Junio C HamanoSep 2, 2015
  40. Jeff KingSep 2, 2015
  41. 00/11 Make "local" orthogonal to date formatJohn Keeping, Sep 3, 2015
  42. 01/11 Documentation/blame-options: don't list date formatsJohn Keeping, Sep 3, 2015
  43. 02/11 Documentation/config: don't list date formatsJohn Keeping, Sep 3, 2015
  44. 03/11 Documentation/git-for-each-ref: don't list date formatsJohn Keeping, Sep 3, 2015
  45. 04/11 Documentation/rev-list: don't list date formatsJohn Keeping, Sep 3, 2015
  46. Junio C HamanoSep 3, 2015
  47. 05/11 fast-import: switch crash-report date to iso8601John Keeping, Sep 3, 2015
  48. 06/11 t6300: introduce test_date() helperJohn Keeping, Sep 3, 2015
  49. 07/11 t6300: add test for "raw" date formatJohn Keeping, Sep 3, 2015
  50. 08/11 date: check for "local" before anything elseJohn Keeping, Sep 3, 2015
  51. Junio C HamanoSep 3, 2015
  52. 09/11 date: make "local" orthogonal to date formatJohn Keeping, Sep 3, 2015
  53. 10/11 t6300: make UTC and local dates differentJohn Keeping, Sep 3, 2015
  54. 11/11 t6300: add tests for "-local" date formatsJohn Keeping, Sep 3, 2015
  55. Jeff KingSep 8, 2015
  56. Junio C HamanoSep 2, 2015
  57. Jeff KingSep 2, 2015
  58. John KeepingSep 2, 2015
  59. Junio C HamanoSep 3, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.