threads / patch / 9025

patchSupport output ISO 8601 format dates

Subject: [PATCH] Support output ISO 8601 format dates

## tl;dr

13 messages between Jul 13, 2007 and Jul 15, 2007. Diffs are folded; open one to read it.

replies: 12people: 5as markdown or json

Robin Rosenberg· Jul 13, 2007, 20:22 UTC · lore

Support output of full ISO 8601 style dates in e.g. git log and other places that use interpolation for formatting.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 cache.h  |    2 +-
 commit.c |    6 +++++-
 date.c   |    7 +++++++
 3 files changed, 13 insertions(+), 2 deletions(-)
Show changes to 3 files +13 −2

cache.h, commit.c, date.c

diff --git a/cache.h b/cache.h
index 5dff2f1..3dc0def 100644
--- a/cache.h
+++ b/cache.h
@@ -389,7 +389,7 @@ extern void *read_object_with_reference(const unsigned char *sha1,
 					unsigned long *size,
 					unsigned char *sha1_ret);
 
-enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT, DATE_LOCAL };
+enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT, DATE_LOCAL, DATE_ISO8601 };
 const char *show_date(unsigned long time, int timezone, enum date_mode mode);
 const char *show_rfc2822_date(unsigned long time, int timezone);
 int parse_date(const char *date, char *buf, int bufsize);
diff --git a/commit.c b/commit.c
index 5632e32..68df3b4 100644
--- a/commit.c
+++ b/commit.c
@@ -773,6 +773,7 @@ static void fill_person(struct interp *table, const char *msg, int len)
 	interp_set_entry(table, 2, show_date(date, tz, 0));
 	interp_set_entry(table, 3, show_rfc2822_date(date, tz));
 	interp_set_entry(table, 4, show_date(date, tz, 1));
+	interp_set_entry(table, 6, show_date(date, tz, DATE_ISO8601));
 }
 
 static long format_commit_message(const struct commit *commit,
@@ -791,12 +792,14 @@ static long format_commit_message(const struct commit *commit,
 		{ "%aD" },	/* author date, RFC2822 style */
 		{ "%ar" },	/* author date, relative */
 		{ "%at" },	/* author date, UNIX timestamp */
+		{ "%ai" },	/* author date, ISO 8601 */
 		{ "%cn" },	/* committer name */
 		{ "%ce" },	/* committer email */
 		{ "%cd" },	/* committer date */
 		{ "%cD" },	/* committer date, RFC2822 style */
 		{ "%cr" },	/* committer date, relative */
 		{ "%ct" },	/* committer date, UNIX timestamp */
+		{ "%ci" },	/* committer date, ISO 8601 */
 		{ "%e" },	/* encoding */
 		{ "%s" },	/* subject */
 		{ "%b" },	/* body */
@@ -813,10 +816,11 @@ static long format_commit_message(const struct commit *commit,
 		IPARENTS, IPARENTS_ABBREV,
 		IAUTHOR_NAME, IAUTHOR_EMAIL,
 		IAUTHOR_DATE, IAUTHOR_DATE_RFC2822, IAUTHOR_DATE_RELATIVE,
-		IAUTHOR_TIMESTAMP,
+		IAUTHOR_TIMESTAMP, IAUTHOR_ISO8601,
 		ICOMMITTER_NAME, ICOMMITTER_EMAIL,
 		ICOMMITTER_DATE, ICOMMITTER_DATE_RFC2822,
 		ICOMMITTER_DATE_RELATIVE, ICOMMITTER_TIMESTAMP,
+		ICOMMITTER_ISO8601,
 		IENCODING,
 		ISUBJECT,
 		IBODY,
diff --git a/date.c b/date.c
index 4690371..5155bb2 100644
--- a/date.c
+++ b/date.c
@@ -137,6 +137,13 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)
 	if (mode == DATE_SHORT)
 		sprintf(timebuf, "%04d-%02d-%02d", tm->tm_year + 1900,
 				tm->tm_mon + 1, tm->tm_mday);
+	else if (mode == DATE_ISO8601)
+		sprintf(timebuf, "%04d-%02d-%02d %02d:%02d:%02d %+05d",
+				tm->tm_year + 1900,
+				tm->tm_mon + 1,
+				tm->tm_mday,
+				tm->tm_hour, tm->tm_min, tm->tm_sec,
+				tz);
 	else
 		sprintf(timebuf, "%.3s %.3s %d %02d:%02d:%02d %d%c%+05d",
 				weekday_names[tm->tm_wday],
Junio C Hamano· Jul 13, 2007, 22:11 UTC · re: Robin Rosenberg · lore

Re: [PATCH] Support output ISO 8601 format dates

Documentation/pretty-formats.txt does not talk about this addition.

Almost everything else looks fine with your patch, except that neither "git show --date=iso" nor "git log --date=iso8601" works with this change, but that is only half your fault.

When we added DATE_SHORT support we could have added the option parser to revision.c so that you could mimick it more easily. That half is my fault.

The patch, especially this hunk:
Show 12 quoted lines
> diff --git a/commit.c b/commit.c
> index 5632e32..68df3b4 100644
> --- a/commit.c
> +++ b/commit.c
> @@ -773,6 +773,7 @@ static void fill_person(struct interp *table, const char *msg, int len)
>  	interp_set_entry(table, 2, show_date(date, tz, 0));
>  	interp_set_entry(table, 3, show_rfc2822_date(date, tz));
>  	interp_set_entry(table, 4, show_date(date, tz, 1));
> +	interp_set_entry(table, 6, show_date(date, tz, DATE_ISO8601));
>  }
>  
>  static long format_commit_message(const struct commit *commit,

makes me wonder if we would want to refactor and reimplement show_rfc2822_date() in terms of show_date(), by introducing DATE_RFC2822 in the date format enum, which will allow us to say "git show --date=rfc2822".

Hmm?
Robin Rosenberg· Jul 13, 2007, 23:00 UTC · re: Junio C Hamano · lore

Support output of full ISO 8601 style dates in e.g. git log and other places that use interpolation for formatting.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---

Updated docs too. The show --date is not included because I didn't know about it.

 Documentation/pretty-formats.txt |    2 ++
 cache.h                          |    2 +-
 commit.c                         |    6 +++++-
 date.c                           |    7 +++++++
 4 files changed, 15 insertions(+), 2 deletions(-)
Show changes to 4 files +15 −2

Documentation/pretty-formats.txt, cache.h, commit.c, date.c

diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index d922e8e..1296b31 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -106,12 +106,14 @@ The placeholders are:
 - '%aD': author date, RFC2822 style
 - '%ar': author date, relative
 - '%at': author date, UNIX timestamp
+- '%ai': author date, ISO 8601 format
 - '%cn': committer name
 - '%ce': committer email
 - '%cd': committer date
 - '%cD': committer date, RFC2822 style
 - '%cr': committer date, relative
 - '%ct': committer date, UNIX timestamp
+- '%ci': committer date, ISO 8601 format
 - '%e': encoding
 - '%s': subject
 - '%b': body
diff --git a/cache.h b/cache.h
index 5dff2f1..3dc0def 100644
--- a/cache.h
+++ b/cache.h
@@ -389,7 +389,7 @@ extern void *read_object_with_reference(const unsigned char *sha1,
 					unsigned long *size,
 					unsigned char *sha1_ret);
 
-enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT, DATE_LOCAL };
+enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT, DATE_LOCAL, DATE_ISO8601 };
 const char *show_date(unsigned long time, int timezone, enum date_mode mode);
 const char *show_rfc2822_date(unsigned long time, int timezone);
 int parse_date(const char *date, char *buf, int bufsize);
diff --git a/commit.c b/commit.c
index 5632e32..68df3b4 100644
--- a/commit.c
+++ b/commit.c
@@ -773,6 +773,7 @@ static void fill_person(struct interp *table, const char *msg, int len)
 	interp_set_entry(table, 2, show_date(date, tz, 0));
 	interp_set_entry(table, 3, show_rfc2822_date(date, tz));
 	interp_set_entry(table, 4, show_date(date, tz, 1));
+	interp_set_entry(table, 6, show_date(date, tz, DATE_ISO8601));
 }
 
 static long format_commit_message(const struct commit *commit,
@@ -791,12 +792,14 @@ static long format_commit_message(const struct commit *commit,
 		{ "%aD" },	/* author date, RFC2822 style */
 		{ "%ar" },	/* author date, relative */
 		{ "%at" },	/* author date, UNIX timestamp */
+		{ "%ai" },	/* author date, ISO 8601 */
 		{ "%cn" },	/* committer name */
 		{ "%ce" },	/* committer email */
 		{ "%cd" },	/* committer date */
 		{ "%cD" },	/* committer date, RFC2822 style */
 		{ "%cr" },	/* committer date, relative */
 		{ "%ct" },	/* committer date, UNIX timestamp */
+		{ "%ci" },	/* committer date, ISO 8601 */
 		{ "%e" },	/* encoding */
 		{ "%s" },	/* subject */
 		{ "%b" },	/* body */
@@ -813,10 +816,11 @@ static long format_commit_message(const struct commit *commit,
 		IPARENTS, IPARENTS_ABBREV,
 		IAUTHOR_NAME, IAUTHOR_EMAIL,
 		IAUTHOR_DATE, IAUTHOR_DATE_RFC2822, IAUTHOR_DATE_RELATIVE,
-		IAUTHOR_TIMESTAMP,
+		IAUTHOR_TIMESTAMP, IAUTHOR_ISO8601,
 		ICOMMITTER_NAME, ICOMMITTER_EMAIL,
 		ICOMMITTER_DATE, ICOMMITTER_DATE_RFC2822,
 		ICOMMITTER_DATE_RELATIVE, ICOMMITTER_TIMESTAMP,
+		ICOMMITTER_ISO8601,
 		IENCODING,
 		ISUBJECT,
 		IBODY,
diff --git a/date.c b/date.c
index 4690371..5155bb2 100644
--- a/date.c
+++ b/date.c
@@ -137,6 +137,13 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)
 	if (mode == DATE_SHORT)
 		sprintf(timebuf, "%04d-%02d-%02d", tm->tm_year + 1900,
 				tm->tm_mon + 1, tm->tm_mday);
+	else if (mode == DATE_ISO8601)
+		sprintf(timebuf, "%04d-%02d-%02d %02d:%02d:%02d %+05d",
+				tm->tm_year + 1900,
+				tm->tm_mon + 1,
+				tm->tm_mday,
+				tm->tm_hour, tm->tm_min, tm->tm_sec,
+				tz);
 	else
 		sprintf(timebuf, "%.3s %.3s %d %02d:%02d:%02d %d%c%+05d",
 				weekday_names[tm->tm_wday],
Junio C Hamano· Jul 14, 2007, 06:42 UTC · re: Robin Rosenberg · lore

[PATCH 1/2] Make show_rfc2822_date() just another date output format.

These days, show_date() takes a date_mode parameter to specify the output format, and a separate specialized function for dates in E-mails does not make much sense anymore.

This retires show_rfc2822_date() function and make it just another date output format.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Robin Rosenberg <robin.rosenberg@dewire.com> writes:
 > Updated docs too. The show --date is not included because I didn't know
 > about it.
 Thanks.  Here is what I had in mind when I "wondered" aloud earlier...
 cache.h     |   11 +++++++++--
 commit.c    |    8 ++++----
 date.c      |   20 +++++---------------
 refs.c      |    4 ++--
 sha1_name.c |    2 +-
 5 files changed, 21 insertions(+), 24 deletions(-)
Show changes to 5 files +21 −24

cache.h, commit.c, date.c, refs.c, sha1_name.c

diff --git a/cache.h b/cache.h
index b39557d..328c1ad 100644
--- a/cache.h
+++ b/cache.h
@@ -409,9 +409,16 @@ extern void *read_object_with_reference(const unsigned char *sha1,
 					unsigned long *size,
 					unsigned char *sha1_ret);
 
-enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT, DATE_LOCAL, DATE_ISO8601 };
+enum date_mode {
+	DATE_NORMAL = 0,
+	DATE_RELATIVE,
+	DATE_SHORT,
+	DATE_LOCAL,
+	DATE_ISO8601,
+	DATE_RFC2822
+};
+
 const char *show_date(unsigned long time, int timezone, enum date_mode mode);
-const char *show_rfc2822_date(unsigned long time, int timezone);
 int parse_date(const char *date, char *buf, int bufsize);
 void datestamp(char *buf, int bufsize);
 unsigned long approxidate(const char *);
diff --git a/commit.c b/commit.c
index d11941c..4c5dfa9 100644
--- a/commit.c
+++ b/commit.c
@@ -585,7 +585,7 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf,
 		break;
 	case CMIT_FMT_EMAIL:
 		ret += sprintf(buf + ret, "Date: %s\n",
-			       show_rfc2822_date(time, tz));
+			       show_date(time, tz, DATE_RFC2822));
 		break;
 	case CMIT_FMT_FULLER:
 		ret += sprintf(buf + ret, "%sDate: %s\n", what,
@@ -778,9 +778,9 @@ static void fill_person(struct interp *table, const char *msg, int len)
 			tz = -tz;
 	}
 
-	interp_set_entry(table, 2, show_date(date, tz, 0));
-	interp_set_entry(table, 3, show_rfc2822_date(date, tz));
-	interp_set_entry(table, 4, show_date(date, tz, 1));
+	interp_set_entry(table, 2, show_date(date, tz, DATE_NORMAL));
+	interp_set_entry(table, 3, show_date(date, tz, DATE_RFC2822));
+	interp_set_entry(table, 4, show_date(date, tz, DATE_RELATIVE));
 	interp_set_entry(table, 6, show_date(date, tz, DATE_ISO8601));
 }
 
diff --git a/date.c b/date.c
index 735d8f3..45b0b1d 100644
--- a/date.c
+++ b/date.c
@@ -144,6 +144,11 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)
 				tm->tm_mday,
 				tm->tm_hour, tm->tm_min, tm->tm_sec,
 				tz);
+	else if (mode == DATE_RFC2822)
+		sprintf(timebuf, "%.3s, %d %.3s %d %02d:%02d:%02d %+05d",
+			weekday_names[tm->tm_wday], tm->tm_mday,
+			month_names[tm->tm_mon], tm->tm_year + 1900,
+			tm->tm_hour, tm->tm_min, tm->tm_sec, tz);
 	else
 		sprintf(timebuf, "%.3s %.3s %d %02d:%02d:%02d %d%c%+05d",
 				weekday_names[tm->tm_wday],
@@ -156,21 +161,6 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)
 	return timebuf;
 }
 
-const char *show_rfc2822_date(unsigned long time, int tz)
-{
-	struct tm *tm;
-	static char timebuf[200];
-
-	tm = time_to_tm(time, tz);
-	if (!tm)
-		return NULL;
-	sprintf(timebuf, "%.3s, %d %.3s %d %02d:%02d:%02d %+05d",
-		weekday_names[tm->tm_wday], tm->tm_mday,
-		month_names[tm->tm_mon], tm->tm_year + 1900,
-		tm->tm_hour, tm->tm_min, tm->tm_sec, tz);
-	return timebuf;
-}
-
 /*
  * Check these. And note how it doesn't do the summer-time conversion.
  *
diff --git a/refs.c b/refs.c
index 4dc7e8b..2694e70 100644
--- a/refs.c
+++ b/refs.c
@@ -1300,7 +1300,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
 				if (hashcmp(logged_sha1, sha1)) {
 					fprintf(stderr,
 						"warning: Log %s has gap after %s.\n",
-						logfile, show_rfc2822_date(date, tz));
+						logfile, show_date(date, tz, DATE_RFC2822));
 				}
 			}
 			else if (date == at_time) {
@@ -1313,7 +1313,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
 				if (hashcmp(logged_sha1, sha1)) {
 					fprintf(stderr,
 						"warning: Log %s unexpectedly ended on %s.\n",
-						logfile, show_rfc2822_date(date, tz));
+						logfile, show_date(date, tz, DATE_RFC2822));
 				}
 			}
 			munmap(log_mapped, mapsz);
diff --git a/sha1_name.c b/sha1_name.c
index 858f08c..2d727d5 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -370,7 +370,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
 				fprintf(stderr,
 					"warning: Log for '%.*s' only goes "
 					"back to %s.\n", len, str,
-					show_rfc2822_date(co_time, co_tz));
+					show_date(co_time, co_tz, DATE_RFC2822));
 			else
 				fprintf(stderr,
 					"warning: Log for '%.*s' only has "
-- 
1.5.3.rc1.4.gaf83
Junio C Hamano· Jul 14, 2007, 06:43 UTC · re: Robin Rosenberg · lore

[PATCH 2/2] Wire new date formats to --date=<format> parser.

Now we can use all internally supported date formats with
	git log --date=<format>
syntax.  Earlier, we only allowed relative/local/default.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 revision.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)
Show changes to revision.c +8 −0
diff --git a/revision.c b/revision.c
index 27cce09..28b5f2e 100644
--- a/revision.c
+++ b/revision.c
@@ -1133,6 +1133,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
 			if (!strncmp(arg, "--date=", 7)) {
 				if (!strcmp(arg + 7, "relative"))
 					revs->date_mode = DATE_RELATIVE;
+				else if (!strcmp(arg + 7, "iso8601") ||
+					 !strcmp(arg + 7, "iso"))
+					revs->date_mode = DATE_ISO8601;
+				else if (!strcmp(arg + 7, "rfc2822") ||
+					 !strcmp(arg + 7, "rfc"))
+					revs->date_mode = DATE_RFC2822;
+				else if (!strcmp(arg + 7, "short"))
+					revs->date_mode = DATE_SHORT;
 				else if (!strcmp(arg + 7, "local"))
 					revs->date_mode = DATE_LOCAL;
 				else if (!strcmp(arg + 7, "default"))
-- 
1.5.3.rc1.4.gaf83
Jan-Benedict Glaw· Jul 14, 2007, 06:44 UTC · re: Junio C Hamano · lore

Re: [PATCH 2/2] Wire new date formats to --date=<format> parser.

On Fri, 2007-07-13 23:43:00 -0700, Junio C Hamano <gitster@pobox.com> wrote:
Show 11 quoted lines
> --- a/revision.c
> +++ b/revision.c
> @@ -1133,6 +1133,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
>  			if (!strncmp(arg, "--date=", 7)) {
>  				if (!strcmp(arg + 7, "relative"))
>  					revs->date_mode = DATE_RELATIVE;
> +				else if (!strcmp(arg + 7, "iso8601") ||
> +					 !strcmp(arg + 7, "iso"))
> +					revs->date_mode = DATE_ISO8601;
> +				else if (!strcmp(arg + 7, "rfc2822") ||
> +					 !strcmp(arg + 7, "rfc"))
Maybe also add "rfc822"?
Show 6 quoted lines
> +					revs->date_mode = DATE_RFC2822;
> +				else if (!strcmp(arg + 7, "short"))
> +					revs->date_mode = DATE_SHORT;
>  				else if (!strcmp(arg + 7, "local"))
>  					revs->date_mode = DATE_LOCAL;
>  				else if (!strcmp(arg + 7, "default"))
MfG, JBG
-- 
      Jan-Benedict Glaw      jbglaw@lug-owl.de              +49-172-7608481
Signature of:            http://www.chiark.greenend.org.uk/~sgtatham/bugs.html
the second  :
Junio C Hamano· Jul 14, 2007, 06:54 UTC · re: Jan-Benedict Glaw · lore

Re: [PATCH 2/2] Wire new date formats to --date=<format> parser.

Jan-Benedict Glaw <jbglaw@lug-owl.de> writes:
Show 14 quoted lines
> On Fri, 2007-07-13 23:43:00 -0700, Junio C Hamano <gitster@pobox.com> wrote:
>> --- a/revision.c
>> +++ b/revision.c
>> @@ -1133,6 +1133,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
>>  			if (!strncmp(arg, "--date=", 7)) {
>>  				if (!strcmp(arg + 7, "relative"))
>>  					revs->date_mode = DATE_RELATIVE;
>> +				else if (!strcmp(arg + 7, "iso8601") ||
>> +					 !strcmp(arg + 7, "iso"))
>> +					revs->date_mode = DATE_ISO8601;
>> +				else if (!strcmp(arg + 7, "rfc2822") ||
>> +					 !strcmp(arg + 7, "rfc"))
>
> Maybe also add "rfc822"?

I've thought about it, but did not bother; I suspect people would just say "rfc" anyway.

Robin Rosenberg· Jul 14, 2007, 10:29 UTC · re: Junio C Hamano · lore

Re: [PATCH 2/2] Wire new date formats to --date=<format> parser.

lördag 14 juli 2007 skrev Junio C Hamano:
Show 7 quoted lines
> Now we can use all internally supported date formats with
> 
> 	git log --date=<format>
> 
> syntax.  Earlier, we only allowed relative/local/default.
> 
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Ack, 1/2 and 2/2.
-- robin
Junio C Hamano· Jul 14, 2007, 06:49 UTC · re: Robin Rosenberg · lore

[PATCH] Document new --date=<format>

Now, git-log family can take full range of internally supported date format to their --date=<format> argument. Document it.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 * And the documentation...
 Documentation/git-rev-list.txt |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)
Show changes to Documentation/git-rev-list.txt +9 −1
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index 20dcac6..08e7573 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -28,7 +28,7 @@ SYNOPSIS
 	     [ \--encoding[=<encoding>] ]
 	     [ \--(author|committer|grep)=<pattern> ]
 	     [ \--regexp-ignore-case ] [ \--extended-regexp ]
-	     [ \--date={local|relative|default} ]
+	     [ \--date={local|relative|default|iso|rfc|short} ]
 	     [ [\--objects | \--objects-edge] [ \--unpacked ] ]
 	     [ \--pretty | \--header ]
 	     [ \--bisect ]
@@ -96,7 +96,7 @@ include::pretty-options.txt[]
 
 	Synonym for `--date=relative`.
 
---date={relative,local,default}::
+--date={relative,local,default,iso,rfc}::
 
 	Only takes effect for dates shown in human-readable format, such
 	as when using "--pretty".
@@ -106,6 +106,13 @@ e.g. "2 hours ago".
 +
 `--date=local` shows timestamps in user's local timezone.
 +
+`--date=iso` (or `--date=iso8601`) shows timestamps in ISO 8601 format.
++
+`--date=rfc` (or `--date=rfc2822`) shows timestamps in RFC 2822
+format, often found in E-mail messages.
++
+`--date=short` shows only date but not time, in `YYYY-MM-DD` fomat.
++
 `--date=default` shows timestamps in the original timezone
 (either committer's or author's).
 
-- 
1.5.3.rc1.4.gaf83
Jan Hudec· Jul 15, 2007, 21:23 UTC · re: Robin Rosenberg · lore

Re: [PATCH] Support output ISO 8601 format dates

Hello,
On Fri, Jul 13, 2007 at 22:22:58 +0200, Robin Rosenberg wrote:
Show 7 quoted lines
> +	else if (mode == DATE_ISO8601)
> +		sprintf(timebuf, "%04d-%02d-%02d %02d:%02d:%02d %+05d",
> +				tm->tm_year + 1900,
> +				tm->tm_mon + 1,
> +				tm->tm_mday,
> +				tm->tm_hour, tm->tm_min, tm->tm_sec,
> +				tz);

I apologise for nitpicking, but ISO 8601 (and RFC 3339) says separator between date and time is 'T' and there is no separator between time and timezone. So this should be

+		sprintf(timebuf, "%04d-%02d-%02dT%02d:%02d:%02d%+05d",

for 100% conformance to the standard. RFC 3339 explicitely mentions using space instead of 'T' as separator as allowed, but does not seem to mention space before time zone. There may be applications that would stop at such space and assume no timezone information.

Furthermore RFC 3339 seems to require colon in the timezone, so it would be:

+ sprintf(timebuf, "%04d-%02d-%02dT%02d:%02d:%02d%+03d:%02d", + tm->tm_year + 1900, + tm->tm_mon + 1, + tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, + tz / 100, abs(tz % 100));

ISO 8601 makes separators optional, so simple 4-digit timezone is OK.
-- 
						 Jan 'Bulb' Hudec <bulb@ucw.cz>
Junio C Hamano· Jul 15, 2007, 22:14 UTC · re: Jan Hudec · lore

Re: [PATCH] Support output ISO 8601 format dates

Jan Hudec <bulb@ucw.cz> writes:
Show 5 quoted lines
> I apologise for nitpicking, but ISO 8601 (and RFC 3339) says separator between
> date and time is 'T' and there is no separator between time and timezone. So
> this should be
> ...
> ISO 8601 makes separators optional, so simple 4-digit timezone is OK.

My reading of 8601 was that it is allowed to drop [T] as long as it is clear from the context by agreement between the parties involved, although I admit the only copy I have handy is JIS X0301 (2002), which is matching Japanese industrial standard that consists of translation of ISO 8601 (2000) plus Japanese "emperor's era" extensions.

Robin Rosenberg· Jul 15, 2007, 23:19 UTC · re: Jan Hudec · lore

Re: [PATCH] Support output ISO 8601 format dates

From 59eafc201aec3be121b33c2ecf16c70cc3521e92 Mon Sep 17 00:00:00 2001
From: Robin Rosenberg <robin.rosenberg@dewire.com>
Date: Mon, 16 Jul 2007 01:05:19 +0200
Subject: [PATCH] Support output ISO 8601 format dates

Support output of full ISO 8601 style dates in e.g. git log and other places that use interpolation for formatting.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 Documentation/pretty-formats.txt |    2 ++
 cache.h                          |    2 +-
 commit.c                         |    6 +++++-
 date.c                           |    9 +++++++++
 4 files changed, 17 insertions(+), 2 deletions(-)
söndag 15 juli 2007 skrev Jan Hudec:
Show 16 quoted lines
> Hello,
> 
> On Fri, Jul 13, 2007 at 22:22:58 +0200, Robin Rosenberg wrote:
> > +	else if (mode == DATE_ISO8601)
> > +		sprintf(timebuf, "%04d-%02d-%02d %02d:%02d:%02d %+05d",
> > +				tm->tm_year + 1900,
> > +				tm->tm_mon + 1,
> > +				tm->tm_mday,
> > +				tm->tm_hour, tm->tm_min, tm->tm_sec,
> > +				tz);
> 
> I apologise for nitpicking, but ISO 8601 (and RFC 3339) says separator between
> date and time is 'T' and there is no separator between time and timezone. So
> this should be
> 
> +		sprintf(timebuf, "%04d-%02d-%02dT%02d:%02d:%02d%+05d",

Note that my reference is to ISO 8601, not RFC 3339. Hower I interpret "NOTE By mutual agreement of the partners in information interchange, the character [T] may be omitted in applications where there is no risk of confusing a date and time of day representation with others defined in this International Standard" (ISO 8601:2004 4.3.2) as space being allowed here instead of 'T'.

By "mutual agreement" I mean that I tell you what it looks like and you agree :)
I agree with you about the space before timezone though. I'll go.
Show 15 quoted lines
> for 100% conformance to the standard. RFC 3339 explicitely mentions using
> space instead of 'T' as separator as allowed, but does not seem to mention
> space before time zone. There may be applications that would stop at such
> space and assume no timezone information.
> 
> Furthermore RFC 3339 seems to require colon in the timezone, so it would be:
> 
> +		sprintf(timebuf, "%04d-%02d-%02dT%02d:%02d:%02d%+03d:%02d",
> +				tm->tm_year + 1900,
> +				tm->tm_mon + 1,
> +				tm->tm_mday,
> +				tm->tm_hour, tm->tm_min, tm->tm_sec,
> +				tz / 100, abs(tz % 100));
> 
> ISO 8601 makes separators optional, so simple 4-digit timezone is OK.

For the sake of consequence I should use the extended format for all parts and not mix basic and extended formats.

Updated patch follows that formats dates as "2006-08-17 20:59:46+05:30"
-- robin
Show changes to 4 files +17 −2

Documentation/pretty-formats.txt, cache.h, commit.c, date.c

diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index d922e8e..1296b31 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -106,12 +106,14 @@ The placeholders are:
 - '%aD': author date, RFC2822 style
 - '%ar': author date, relative
 - '%at': author date, UNIX timestamp
+- '%ai': author date, ISO 8601 format
 - '%cn': committer name
 - '%ce': committer email
 - '%cd': committer date
 - '%cD': committer date, RFC2822 style
 - '%cr': committer date, relative
 - '%ct': committer date, UNIX timestamp
+- '%ci': committer date, ISO 8601 format
 - '%e': encoding
 - '%s': subject
 - '%b': body
diff --git a/cache.h b/cache.h
index 5dff2f1..3dc0def 100644
--- a/cache.h
+++ b/cache.h
@@ -389,7 +389,7 @@ extern void *read_object_with_reference(const unsigned char *sha1,
 					unsigned long *size,
 					unsigned char *sha1_ret);
 
-enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT, DATE_LOCAL };
+enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT, DATE_LOCAL, DATE_ISO8601 };
 const char *show_date(unsigned long time, int timezone, enum date_mode mode);
 const char *show_rfc2822_date(unsigned long time, int timezone);
 int parse_date(const char *date, char *buf, int bufsize);
diff --git a/commit.c b/commit.c
index 5632e32..68df3b4 100644
--- a/commit.c
+++ b/commit.c
@@ -773,6 +773,7 @@ static void fill_person(struct interp *table, const char *msg, int len)
 	interp_set_entry(table, 2, show_date(date, tz, 0));
 	interp_set_entry(table, 3, show_rfc2822_date(date, tz));
 	interp_set_entry(table, 4, show_date(date, tz, 1));
+	interp_set_entry(table, 6, show_date(date, tz, DATE_ISO8601));
 }
 
 static long format_commit_message(const struct commit *commit,
@@ -791,12 +792,14 @@ static long format_commit_message(const struct commit *commit,
 		{ "%aD" },	/* author date, RFC2822 style */
 		{ "%ar" },	/* author date, relative */
 		{ "%at" },	/* author date, UNIX timestamp */
+		{ "%ai" },	/* author date, ISO 8601 */
 		{ "%cn" },	/* committer name */
 		{ "%ce" },	/* committer email */
 		{ "%cd" },	/* committer date */
 		{ "%cD" },	/* committer date, RFC2822 style */
 		{ "%cr" },	/* committer date, relative */
 		{ "%ct" },	/* committer date, UNIX timestamp */
+		{ "%ci" },	/* committer date, ISO 8601 */
 		{ "%e" },	/* encoding */
 		{ "%s" },	/* subject */
 		{ "%b" },	/* body */
@@ -813,10 +816,11 @@ static long format_commit_message(const struct commit *commit,
 		IPARENTS, IPARENTS_ABBREV,
 		IAUTHOR_NAME, IAUTHOR_EMAIL,
 		IAUTHOR_DATE, IAUTHOR_DATE_RFC2822, IAUTHOR_DATE_RELATIVE,
-		IAUTHOR_TIMESTAMP,
+		IAUTHOR_TIMESTAMP, IAUTHOR_ISO8601,
 		ICOMMITTER_NAME, ICOMMITTER_EMAIL,
 		ICOMMITTER_DATE, ICOMMITTER_DATE_RFC2822,
 		ICOMMITTER_DATE_RELATIVE, ICOMMITTER_TIMESTAMP,
+		ICOMMITTER_ISO8601,
 		IENCODING,
 		ISUBJECT,
 		IBODY,
diff --git a/date.c b/date.c
index 4690371..c96100e 100644
--- a/date.c
+++ b/date.c
@@ -137,7 +137,15 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)
 	if (mode == DATE_SHORT)
 		sprintf(timebuf, "%04d-%02d-%02d", tm->tm_year + 1900,
 				tm->tm_mon + 1, tm->tm_mday);
+	else if (mode == DATE_ISO8601)
+		sprintf(timebuf, "%04d-%02d-%02d %02d:%02d:%02d%+03d:%02d",
+				tm->tm_year + 1900,
+				tm->tm_mon + 1,
+				tm->tm_mday,
+				tm->tm_hour, tm->tm_min, tm->tm_sec,
+				tz/100,
+				abs(tz%100)
+				);
 	else
 		sprintf(timebuf, "%.3s %.3s %d %02d:%02d:%02d %d%c%+05d",
 				weekday_names[tm->tm_wday],
-- 
1.5.2.3

← back to recent threads