threads / patch / 3797

patchparse_date(): fix parsing 03/10/2006

Subject: [PATCH] parse_date(): fix parsing 03/10/2006

## tl;dr

8 messages between Apr 5, 2006 and Jul 14, 2006. Diffs are folded; open one to read it.

replies: 7people: 4as markdown or json

Junio C Hamano· Apr 5, 2006, 06:00 UTC · lore

The comment associated with the date parsing code for three numbers separated with slashes or dashes implied we wanted to interpret using this order:

	yyyy-mm-dd
	yyyy-dd-mm
	mm-dd-yy
	dd-mm-yy

However, the actual code had the last two wrong, and making it prefer dd-mm-yy format over mm-dd-yy.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 * Spotted, thanks to Len Brown and Andrew Morton.
 date.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
f5cd7df6e8322a0b783668b31881ab95a5ce33bd
Show changes to date.c +2 −2
diff --git a/date.c b/date.c
index 416ea57..18a0710 100644
--- a/date.c
+++ b/date.c
@@ -257,10 +257,10 @@ static int match_multi_number(unsigned l
 				break;
 		}
 		/* mm/dd/yy ? */
-		if (is_date(num3, num2, num, tm))
+		if (is_date(num3, num, num2, tm))
 			break;
 		/* dd/mm/yy ? */
-		if (is_date(num3, num, num2, tm))
+		if (is_date(num3, num2, num, tm))
 			break;
 		return 0;
 	}
-- 
1.3.0.rc2.g110c
Andrew Morton· Apr 5, 2006, 06:16 UTC · re: Junio C Hamano · lore

Re: [PATCH] parse_date(): fix parsing 03/10/2006

Junio C Hamano <junkio@cox.net> wrote:
Show 12 quoted lines
>
> The comment associated with the date parsing code for three
>  numbers separated with slashes or dashes implied we wanted to
>  interpret using this order:
> 
>  	yyyy-mm-dd
>  	yyyy-dd-mm
>  	mm-dd-yy
>  	dd-mm-yy
> 
>  However, the actual code had the last two wrong, and making it
>  prefer dd-mm-yy format over mm-dd-yy.

But there was a second problem. Once the parsing had misbehaved, Len managed to create a commit which was six months in the future:

commit 8313524a0d466f451a62709aaedf988d8257b21c
Author: Bob Moore <robert.moore@intel.com>
Date:   Tue Oct 3 00:00:00 2006 -0400
    ACPI: ACPICA 20060310

Will your fix prevent that from happening? If not, perhaps some basic sanity checking might be appropriate.

Junio C Hamano· Apr 5, 2006, 06:26 UTC · re: Andrew Morton · lore

Re: [PATCH] parse_date(): fix parsing 03/10/2006

Andrew Morton <akpm@osdl.org> writes:
Show 11 quoted lines
> But there was a second problem.  Once the parsing had misbehaved, Len
> managed to create a commit which was six months in the future:
>
> commit 8313524a0d466f451a62709aaedf988d8257b21c
> Author: Bob Moore <robert.moore@intel.com>
> Date:   Tue Oct 3 00:00:00 2006 -0400
>
>     ACPI: ACPICA 20060310
>
> Will your fix prevent that from happening?  If not, perhaps some basic
> sanity checking might be appropriate.

You _might_ get an e-mail to fix kernel problems from yourself in the future, in which case you would want to commit with future author date, like this ;-).

People would often deal with dates in the past (way in the past when talking about importing foreign SCM history), but probably it would never make sense to do dates way into the future. I'll think about it.

Andrew Morton· Apr 5, 2006, 06:40 UTC · re: Junio C Hamano · lore

Re: [PATCH] parse_date(): fix parsing 03/10/2006

Junio C Hamano <junkio@cox.net> wrote:
Show 24 quoted lines
>
> Andrew Morton <akpm@osdl.org> writes:
> 
> > But there was a second problem.  Once the parsing had misbehaved, Len
> > managed to create a commit which was six months in the future:
> >
> > commit 8313524a0d466f451a62709aaedf988d8257b21c
> > Author: Bob Moore <robert.moore@intel.com>
> > Date:   Tue Oct 3 00:00:00 2006 -0400
> >
> >     ACPI: ACPICA 20060310
> >
> > Will your fix prevent that from happening?  If not, perhaps some basic
> > sanity checking might be appropriate.
> 
> You _might_ get an e-mail to fix kernel problems from yourself
> in the future, in which case you would want to commit with
> future author date, like this ;-).
> 
> People would often deal with dates in the past (way in the past
> when talking about importing foreign SCM history), but probably
> it would never make sense to do dates way into the future.  I'll
> think about it.
> 

Well it doesn't have to be fatal, of course. Some "do you really want to do this [y/n]?" prompt, with a command option to override it. Or simply print a big warning.

Whatever.
Junio C Hamano· Apr 5, 2006, 22:39 UTC · re: Junio C Hamano · lore

[RFC/PATCH] date parsing: be friendlier to our European friends.

This does three things, only applies to cases where the user manually tries to override the author/commit time by environment variables, with non-ISO, non-2822 format date-string:

 - Refuses to use the interpretation to put the date in the
   future; recent kernel history has a commit made with
   10/03/2006 which is recorded as October 3rd.
 - Adds '.' as the possible year-month-date separator.  We
   learned from our European friends on the #git channel that
   dd.mm.yyyy is the norm there.
 - When the separator is '.', we prefer dd.mm.yyyy over
   mm.dd.yyyy; otherwise mm/dd/yy[yy] takes precedence over
   dd/mm/yy[yy].
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 * This is more of a RFC than ready-to-be-merged patch.
   Alternative patches and improvements are welcome.
 date.c |   77 +++++++++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 56 insertions(+), 21 deletions(-)
b9065540826426ac0e4959e869ba7e08d1ae65d8
Show changes to date.c +56 −21
diff --git a/date.c b/date.c
index 376d25d..034d722 100644
--- a/date.c
+++ b/date.c
@@ -197,26 +197,43 @@ static int match_alpha(const char *date,
 	return skip_alpha(date);
 }
 
-static int is_date(int year, int month, int day, struct tm *tm)
+static int is_date(int year, int month, int day, struct tm *now_tm, time_t now, struct tm *tm)
 {
 	if (month > 0 && month < 13 && day > 0 && day < 32) {
+		struct tm check = *tm;
+		struct tm *r = (now_tm ? &check : tm);
+		time_t specified;
+
+		r->tm_mon = month - 1;
+		r->tm_mday = day;
 		if (year == -1) {
-			tm->tm_mon = month-1;
-			tm->tm_mday = day;
-			return 1;
+			if (!now_tm)
+				return 1;
+			r->tm_year = now_tm->tm_year;
 		}
-		if (year >= 1970 && year < 2100) {
-			year -= 1900;
-		} else if (year > 70 && year < 100) {
-			/* ok */
-		} else if (year < 38) {
-			year += 100;
-		} else
+		else if (year >= 1970 && year < 2100)
+			r->tm_year = year - 1900;
+		else if (year > 70 && year < 100)
+			r->tm_year = year;
+		else if (year < 38)
+			r->tm_year = year + 100;
+		else
 			return 0;
+		if (!now_tm)
+			return 1;
+
+		specified = my_mktime(r);
 
-		tm->tm_mon = month-1;
-		tm->tm_mday = day;
-		tm->tm_year = year;
+		/* Be it commit time or author time, it does not make
+		 * sense to specify timestamp way into the future.  Make
+		 * sure it is not later than ten days from now...
+		 */
+		if (now + 10*24*3600 < specified)
+			return 0;
+		tm->tm_mon = r->tm_mon;
+		tm->tm_mday = r->tm_mday;
+		if (year != -1)
+			tm->tm_year = r->tm_year;
 		return 1;
 	}
 	return 0;
@@ -224,6 +241,9 @@ static int is_date(int year, int month, 
 
 static int match_multi_number(unsigned long num, char c, const char *date, char *end, struct tm *tm)
 {
+	time_t now;
+	struct tm now_tm;
+	struct tm *refuse_future;
 	long num2, num3;
 
 	num2 = strtol(end+1, &end, 10);
@@ -246,19 +266,33 @@ static int match_multi_number(unsigned l
 
 	case '-':
 	case '/':
+	case '.':
+		now = time(NULL);
+		refuse_future = NULL;
+		if (gmtime_r(&now, &now_tm))
+			refuse_future = &now_tm;
+
 		if (num > 70) {
 			/* yyyy-mm-dd? */
-			if (is_date(num, num2, num3, tm))
+			if (is_date(num, num2, num3, refuse_future, now, tm))
 				break;
 			/* yyyy-dd-mm? */
-			if (is_date(num, num3, num2, tm))
+			if (is_date(num, num3, num2, refuse_future, now, tm))
 				break;
 		}
-		/* mm/dd/yy ? */
-		if (is_date(num3, num, num2, tm))
+		/* Our eastern European friends say dd.mm.yy[yy]
+		 * is the norm there, so giving precedence to
+		 * mm/dd/yy[yy] form only when separator is not '.'
+		 */
+		if (c != '.' &&
+		    is_date(num3, num, num2, refuse_future, now, tm))
+			break;
+		/* European dd.mm.yy[yy] or funny US dd/mm/yy[yy] */
+		if (is_date(num3, num2, num, refuse_future, now, tm))
 			break;
-		/* dd/mm/yy ? */
-		if (is_date(num3, num2, num, tm))
+		/* Funny European mm.dd.yy */
+		if (c == '.' &&
+		    is_date(num3, num, num2, refuse_future, now, tm))
 			break;
 		return 0;
 	}
@@ -288,10 +322,11 @@ static int match_digit(const char *date,
 	}
 
 	/*
-	 * Check for special formats: num[:-/]num[same]num
+	 * Check for special formats: num[-.:/]num[same]num
 	 */
 	switch (*end) {
 	case ':':
+	case '.':
 	case '/':
 	case '-':
 		if (isdigit(end[1])) {
-- 
1.3.0.rc2.g1b83
Sam Ravnborg· Apr 5, 2006, 22:47 UTC · re: Junio C Hamano · lore

Re: [RFC/PATCH] date parsing: be friendlier to our European friends.

On Wed, Apr 05, 2006 at 03:39:35PM -0700, Junio C Hamano wrote:
Show 11 quoted lines
> This does three things, only applies to cases where the user
> manually tries to override the author/commit time by environment
> variables, with non-ISO, non-2822 format date-string:
> 
>  - Refuses to use the interpretation to put the date in the
>    future; recent kernel history has a commit made with
>    10/03/2006 which is recorded as October 3rd.
> 
>  - Adds '.' as the possible year-month-date separator.  We
>    learned from our European friends on the #git channel that
>    dd.mm.yyyy is the norm there.

I my company we have always used yyyy-mm-dd - this is an ISO standard IIRC. The company is European based.

mm/dd/yy has always made my head spin ;-)
	Sam
Junio C Hamano· Apr 5, 2006, 22:54 UTC · re: Junio C Hamano · lore

Re: [RFC/PATCH] date parsing: be friendlier to our European friends.

Junio C Hamano <junkio@cox.net> writes:
Show 15 quoted lines
> This does three things, only applies to cases where the user
> manually tries to override the author/commit time by environment
> variables, with non-ISO, non-2822 format date-string:
>
>  - Refuses to use the interpretation to put the date in the
>    future; recent kernel history has a commit made with
>    10/03/2006 which is recorded as October 3rd.
>
>  - Adds '.' as the possible year-month-date separator.  We
>    learned from our European friends on the #git channel that
>    dd.mm.yyyy is the norm there.
>
>  - When the separator is '.', we prefer dd.mm.yyyy over
>    mm.dd.yyyy; otherwise mm/dd/yy[yy] takes precedence over
>    dd/mm/yy[yy].

Before the list gets useless comments, the code prefer to accept more sensible and/or unambiguous forms, such as ISO or RFC2822. The issue this addresses is what to do when we get other forms.

David Woodhouse· Jul 14, 2006, 10:26 UTC · re: Junio C Hamano · lore

Re: [RFC/PATCH] date parsing: be friendlier to our European friends.

On Wed, 2006-04-05 at 15:54 -0700, Junio C Hamano wrote:
> Before the list gets useless comments, the code prefer to accept
> more sensible and/or unambiguous forms, such as ISO or RFC2822.
> The issue this addresses is what to do when we get other forms.

Rejecting them and demanding unambiguous forms is better than silently getting it wrong.

-- 
dwmw2

← back to recent threads