{"thread":{"id":"37440","subject":"[PATCH] pretty: Provide a strict ISO8601 date format","startedAt":"2014-08-28T17:49:49Z","lastAt":"2014-08-29T20:57:34Z","messageCount":6,"participants":["Beat Bolli","Junio C Hamano","Scott Schmit"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"248507","messageId":"1409248189-31409-1-git-send-email-bbolli@ewanet.ch","threadId":"37440","inReplyTo":null,"subject":"[PATCH] pretty: Provide a strict ISO8601 date format","fromName":"Beat Bolli","fromEmail":"bbolli@ewanet.ch","sentAt":"2014-08-28T17:49:49Z","receivedAt":"2014-08-28T17:49:49Z","isPatch":true,"sender":{"key":"bbolli@ewanet.ch","avatar":"https://avatars.githubusercontent.com/u/21444?v=4"},"body":"It uses the '%aI' and '%cI' format specifiers or the '--date=iso-strict'\ndate format name.\n\nSee http://article.gmane.org/gmane.comp.version-control.git/255879 for\ndiscussion.\n\nSigned-off-by: Beat Bolli <bbolli@ewanet.ch>\n---\n Documentation/git-rev-list.txt     |  2 +-\n Documentation/pretty-formats.txt   |  6 ++++--\n Documentation/rev-list-options.txt | 13 +++++++++++--\n cache.h                            |  1 +\n date.c                             | 10 ++++++++++\n pretty.c                           |  5 ++++-\n t/t4205-log-pretty-formats.sh      |  7 +++++++\n 7 files changed, 38 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt\nindex 7a1585d..fd7f8b5 100644\n--- a/Documentation/git-rev-list.txt\n+++ b/Documentation/git-rev-list.txt\n@@ -45,7 +45,7 @@ SYNOPSIS\n \t     [ \\--regexp-ignore-case | -i ]\n \t     [ \\--extended-regexp | -E ]\n \t     [ \\--fixed-strings | -F ]\n-\t     [ \\--date=(local|relative|default|iso|rfc|short) ]\n+\t     [ \\--date=(local|relative|default|iso|iso-strict|rfc|short) ]\n \t     [ [\\--objects | \\--objects-edge] [ \\--unpacked ] ]\n \t     [ \\--pretty | \\--header ]\n \t     [ \\--bisect ]\ndiff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\nindex 85d6353..50a2c30 100644\n--- a/Documentation/pretty-formats.txt\n+++ b/Documentation/pretty-formats.txt\n@@ -115,7 +115,8 @@ The placeholders are:\n - '%aD': author date, RFC2822 style\n - '%ar': author date, relative\n - '%at': author date, UNIX timestamp\n-- '%ai': author date, ISO 8601 format\n+- '%ai': author date, ISO 8601-like format\n+- '%aI': author date, strict ISO 8601 format\n - '%cn': committer name\n - '%cN': committer name (respecting .mailmap, see\n   linkgit:git-shortlog[1] or linkgit:git-blame[1])\n@@ -126,7 +127,8 @@ The placeholders are:\n - '%cD': committer date, RFC2822 style\n - '%cr': committer date, relative\n - '%ct': committer date, UNIX timestamp\n-- '%ci': committer date, ISO 8601 format\n+- '%ci': committer date, ISO 8601-like format\n+- '%cI': committer date, strict ISO 8601 format\n - '%d': ref names, like the --decorate option of linkgit:git-log[1]\n - '%e': encoding\n - '%s': subject\ndiff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt\nindex deb8cca..5d311b8 100644\n--- a/Documentation/rev-list-options.txt\n+++ b/Documentation/rev-list-options.txt\n@@ -677,7 +677,7 @@ include::pretty-options.txt[]\n --relative-date::\n \tSynonym for `--date=relative`.\n \n---date=(relative|local|default|iso|rfc|short|raw)::\n+--date=(relative|local|default|iso|iso-strict|rfc|short|raw)::\n \tOnly takes effect for dates shown in human-readable format, such\n \tas when using `--pretty`. `log.date` config variable sets a default\n \tvalue for the log command's `--date` option.\n@@ -687,7 +687,16 @@ e.g. ``2 hours ago''.\n +\n `--date=local` shows timestamps in user's local time zone.\n +\n-`--date=iso` (or `--date=iso8601`) shows timestamps in ISO 8601 format.\n+`--date=iso` (or `--date=iso8601`) shows timestamps in a ISO 8601-like format.\n+The differences to the strict ISO 8601 format are:\n+\n+\t- a space instead of the `T` date/time delimiter\n+\t- a space between time and time zone\n+\t- no colon between hours and minutes of the time zone\n+\n++\n+`--date=iso-strict` (or `--date=iso8601-strict`) shows timestamps in strict\n+ISO 8601 format.\n +\n `--date=rfc` (or `--date=rfc2822`) shows timestamps in RFC 2822\n format, often found in email messages.\ndiff --git a/cache.h b/cache.h\nindex fcb511d..fa92aaf 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1037,6 +1037,7 @@ enum date_mode {\n \tDATE_SHORT,\n \tDATE_LOCAL,\n \tDATE_ISO8601,\n+\tDATE_ISO8601_STRICT,\n \tDATE_RFC2822,\n \tDATE_RAW\n };\ndiff --git a/date.c b/date.c\nindex 782de95..d545ee6 100644\n--- a/date.c\n+++ b/date.c\n@@ -200,6 +200,13 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)\n \t\t\t\ttm->tm_mday,\n \t\t\t\ttm->tm_hour, tm->tm_min, tm->tm_sec,\n \t\t\t\ttz);\n+\telse if (mode == DATE_ISO8601_STRICT)\n+\t\tstrbuf_addf(&timebuf, \"%04d-%02d-%02dT%02d:%02d:%02d%+03d:%02d\",\n+\t\t\t\ttm->tm_year + 1900,\n+\t\t\t\ttm->tm_mon + 1,\n+\t\t\t\ttm->tm_mday,\n+\t\t\t\ttm->tm_hour, tm->tm_min, tm->tm_sec,\n+\t\t\t\ttz / 100, abs(tz % 100));\n \telse if (mode == DATE_RFC2822)\n \t\tstrbuf_addf(&timebuf, \"%.3s, %d %.3s %d %02d:%02d:%02d %+05d\",\n \t\t\tweekday_names[tm->tm_wday], tm->tm_mday,\n@@ -751,6 +758,9 @@ enum date_mode parse_date_format(const char *format)\n \telse if (!strcmp(format, \"iso8601\") ||\n \t\t !strcmp(format, \"iso\"))\n \t\treturn DATE_ISO8601;\n+\telse if (!strcmp(format, \"iso8601-strict\") ||\n+\t\t !strcmp(format, \"iso-strict\"))\n+\t\treturn DATE_ISO8601_STRICT;\n \telse if (!strcmp(format, \"rfc2822\") ||\n \t\t !strcmp(format, \"rfc\"))\n \t\treturn DATE_RFC2822;\ndiff --git a/pretty.c b/pretty.c\nindex 3a1da6f..7dd5601 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -731,9 +731,12 @@ static size_t format_person_part(struct strbuf *sb, char part,\n \tcase 'r':\t/* date, relative */\n \t\tstrbuf_addstr(sb, show_ident_date(&s, DATE_RELATIVE));\n \t\treturn placeholder_len;\n-\tcase 'i':\t/* date, ISO 8601 */\n+\tcase 'i':\t/* date, ISO 8601-like */\n \t\tstrbuf_addstr(sb, show_ident_date(&s, DATE_ISO8601));\n \t\treturn placeholder_len;\n+\tcase 'I':\t/* date, ISO 8601 strict */\n+\t\tstrbuf_addstr(sb, show_ident_date(&s, DATE_ISO8601_STRICT));\n+\t\treturn placeholder_len;\n \t}\n \n skip:\ndiff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh\nindex 349c531..aad7a80 100755\n--- a/t/t4205-log-pretty-formats.sh\n+++ b/t/t4205-log-pretty-formats.sh\n@@ -431,6 +431,13 @@ EOF\n \ttest_cmp expected actual\n '\n \n+# ISO strict date format\n+test_expect_success 'ISO and ISO-strict date formats display the same values' '\n+\tgit log --format=%ai%n%ci | sed -e \"s/ /T/; s/ //; s/..\\$/:&/\" >expected &&\n+\tgit log --format=%aI%n%cI >actual &&\n+\ttest_cmp expected actual\n+'\n+\n # get new digests (with no abbreviations)\n head1=$(git rev-parse --verify HEAD~0) &&\n head2=$(git rev-parse --verify HEAD~1) &&\n-- \n2.1.0\n"},{"id":"248529","messageId":"xmqq61hc8bvq.fsf@gitster.dls.corp.google.com","threadId":"37440","inReplyTo":"1409248189-31409-1-git-send-email-bbolli@ewanet.ch","subject":"Re: [PATCH] pretty: Provide a strict ISO8601 date format","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-08-28T22:53:13Z","receivedAt":"2014-08-28T22:53:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Beat Bolli <bbolli@ewanet.ch> writes:\n\n> It uses the '%aI' and '%cI' format specifiers or the '--date=iso-strict'\n> date format name.\n\nOK.\n\n>\n> See http://article.gmane.org/gmane.comp.version-control.git/255879 for\n> discussion.\n\nPlease think of a way to explain/justify your changes better before\nforcing readers to go online.  In this case, I think what you wrote\nin the updates to the documentation would serve as a good basis for\nit (describe it backwards).\n\n> +The differences to the strict ISO 8601 format are:\n> +\n> +\t- a space instead of the `T` date/time delimiter\n> +\t- a space between time and time zone\n> +\t- no colon between hours and minutes of the time zone\n> +\n> ...\n> -`--date=iso` (or `--date=iso8601`) shows timestamps in ISO 8601 format.\n> +`--date=iso` (or `--date=iso8601`) shows timestamps in a ISO 8601-like format.\n\nShould it be s/a ISO/an ISO/?\n\n> +\telse if (mode == DATE_ISO8601_STRICT)\n> +\t\tstrbuf_addf(&timebuf, \"%04d-%02d-%02dT%02d:%02d:%02d%+03d:%02d\",\n> +\t\t\t\ttm->tm_year + 1900,\n> +\t\t\t\ttm->tm_mon + 1,\n> +\t\t\t\ttm->tm_mday,\n> +\t\t\t\ttm->tm_hour, tm->tm_min, tm->tm_sec,\n> +\t\t\t\ttz / 100, abs(tz % 100));\n\nWouldn't this misidentify a zone that is 30 minutes off of GMT,\ni.e. tz == -30?  tz/100 would not be negative and \"%+03d:\" would\nhappily show \"+00:\", no?\n"},{"id":"248566","messageId":"20140829174439.GA10274@odin.ulthar.us","threadId":"37440","inReplyTo":"xmqq61hc8bvq.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH] pretty: Provide a strict ISO8601 date format","fromName":"Scott Schmit","fromEmail":"i.grok@comcast.net","sentAt":"2014-08-29T17:44:39Z","receivedAt":"2014-08-29T17:44:39Z","isPatch":true,"sender":{"key":"i.grok@comcast.net","avatar":null},"body":"On Thu, Aug 28, 2014 at 03:53:13PM -0700, Junio C Hamano wrote:\n> Beat Bolli writes:\n> > +\telse if (mode == DATE_ISO8601_STRICT)\n> > +\t\tstrbuf_addf(&timebuf, \"%04d-%02d-%02dT%02d:%02d:%02d%+03d:%02d\",\n> > +\t\t\t\ttm->tm_year + 1900,\n> > +\t\t\t\ttm->tm_mon + 1,\n> > +\t\t\t\ttm->tm_mday,\n> > +\t\t\t\ttm->tm_hour, tm->tm_min, tm->tm_sec,\n> > +\t\t\t\ttz / 100, abs(tz % 100));\n> \n> Wouldn't this misidentify a zone that is 30 minutes off of GMT,\n> i.e. tz == -30?  tz/100 would not be negative and \"%+03d:\" would\n> happily show \"+00:\", no?\n\nNo.  strbuf_addf uses strbuf_vaddf which uses vsnprintf(3).  From man\nvsnprintf(3):\n>   The flag characters\n>       The character % is followed by zero or more of the following\n>       flags:\n>\n>       +      A sign (+ or -) should always be placed before a number\n>              produced by a signed conversion.  By default a sign is\n>              used only for negative numbers.  A + overrides a space if\n>              both are used.\n\nPerhaps you misread \"%+03d:\" as \"+%02d:\"?\n\n-- \nScott Schmit\n"},{"id":"248571","messageId":"xmqq1trz6sv0.fsf@gitster.dls.corp.google.com","threadId":"37440","inReplyTo":"20140829174439.GA10274@odin.ulthar.us","subject":"Re: [PATCH] pretty: Provide a strict ISO8601 date format","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-08-29T18:41:39Z","receivedAt":"2014-08-29T18:41:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Scott Schmit <i.grok@comcast.net> writes:\n\n> On Thu, Aug 28, 2014 at 03:53:13PM -0700, Junio C Hamano wrote:\n>> Beat Bolli writes:\n>> > +\telse if (mode == DATE_ISO8601_STRICT)\n>> > +\t\tstrbuf_addf(&timebuf, \"%04d-%02d-%02dT%02d:%02d:%02d%+03d:%02d\",\n>> > +\t\t\t\ttm->tm_year + 1900,\n>> > +\t\t\t\ttm->tm_mon + 1,\n>> > +\t\t\t\ttm->tm_mday,\n>> > +\t\t\t\ttm->tm_hour, tm->tm_min, tm->tm_sec,\n>> > +\t\t\t\ttz / 100, abs(tz % 100));\n>> \n>> Wouldn't this misidentify a zone that is 30 minutes off of GMT,\n>> i.e. tz == -30?  tz/100 would not be negative and \"%+03d:\" would\n>> happily show \"+00:\", no?\n>\n> No.  strbuf_addf uses strbuf_vaddf which uses vsnprintf(3).  From man\n> vsnprintf(3):\n>>   The flag characters\n>>       The character % is followed by zero or more of the following\n>>       flags:\n>>\n>>       +      A sign (+ or -) should always be placed before a number\n>>              produced by a signed conversion.  By default a sign is\n>>              used only for negative numbers.  A + overrides a space if\n>>              both are used.\n>\n> Perhaps you misread \"%+03d:\" as \"+%02d:\"?\n\nI do not think 03 vs 02 makes any difference wrt what I was\nwondering.\n\nYou feed tz/100 to \"%+03d:\" (the \"sign and hour\" part of the\ntimezone).  What if tz is -30, i.e. less than an hour but still a\nnegative offset?  tz/100 would be zero and tz % 100 would be -30.\n\n    tz = -30;\n    printf(\"%+03d:%02d\", tz / 100, abs(tz % 100));\n\nwould show what?\n"},{"id":"248584","messageId":"20140829202916.GB10274@odin.ulthar.us","threadId":"37440","inReplyTo":"xmqq1trz6sv0.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH] pretty: Provide a strict ISO8601 date format","fromName":"Scott Schmit","fromEmail":"i.grok@comcast.net","sentAt":"2014-08-29T20:29:16Z","receivedAt":"2014-08-29T20:29:16Z","isPatch":true,"sender":{"key":"i.grok@comcast.net","avatar":null},"body":"On Fri, Aug 29, 2014 at 11:41:39AM -0700, Junio C Hamano wrote:\n> You feed tz/100 to \"%+03d:\" (the \"sign and hour\" part of the\n> timezone).  What if tz is -30, i.e. less than an hour but still a\n> negative offset?  tz/100 would be zero and tz % 100 would be -30.\n> \n>     tz = -30;\n>     printf(\"%+03d:%02d\", tz / 100, abs(tz % 100));\n> \n> would show what?\n\n+00:30 because zero can't be negative in two's complement arithmetic.\n\nThe \"-30 / 100 = 0\" part didn't click for some reason.  Sorry for the\nnoise.\n"},{"id":"248589","messageId":"xmqq8um75801.fsf@gitster.dls.corp.google.com","threadId":"37440","inReplyTo":"20140829202916.GB10274@odin.ulthar.us","subject":"Re: [PATCH] pretty: Provide a strict ISO8601 date format","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-08-29T20:57:34Z","receivedAt":"2014-08-29T20:57:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Scott Schmit <i.grok@comcast.net> writes:\n\n> +00:30 because zero can't be negative in two's complement arithmetic.\n\nYet to meet negative zero yet myself ;-)\n\n> The \"-30 / 100 = 0\" part didn't click for some reason.  Sorry for the\n> noise.\n\nThat's OK.  You are not the only one who didn't get this right the\nfirst time.  The important thing is that we get it right in the\nversion we will use in the final product.\n\nThanks.\n"}]}