# Clean up approxidate() in preparation for fixes

9 messages from 2006-09-28 to 2006-09-29. Participants: Linus Torvalds, Morten Welinder, Junio C Hamano, Johannes Schindelin.
Thread: https://gitlist.dev/t/5743

## Linus Torvalds, 2006-09-28 19:12

Subject: Clean up approxidate() in preparation for fixes
Message-ID: <Pine.LNX.4.64.0609281211260.3952@g5.osdl.org>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0609281211260.3952%40g5.osdl.org

```

Our approxidate cannot handle simple times like "5 PM yesterday", and to
fix that, we will need to add some logic for number handling.  This just
splits that out into a function of its own (the same way the _real_ date
parsing works).

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---

This should change no code what-so-ever, just split it up in preparation 
for the next patch..

diff --git a/date.c b/date.c
index e387dcd..4ff6604 100644
--- a/date.c
+++ b/date.c
@@ -712,6 +712,15 @@ static const char *approxidate_alpha(con
 	return end;
 }
 
+static const char *approxidate_digit(const char *date, struct tm *tm, int *num)
+{
+	char *end;
+	unsigned long number = strtoul(date, &end, 10);
+
+	*num = number;
+	return end;
+}
+
 unsigned long approxidate(const char *date)
 {
 	int number = 0;
@@ -731,9 +740,7 @@ unsigned long approxidate(const char *da
 			break;
 		date++;
 		if (isdigit(c)) {
-			char *end;
-			number = strtoul(date-1, &end, 10);
-			date = end;
+			date = approxidate_digit(date-1, &tm, &number);
 			continue;
 		}
 		if (isalpha(c))

```

## Linus Torvalds, 2006-09-28 19:14

Subject: Fix approxidate() to understand more extended numbers
Message-ID: <Pine.LNX.4.64.0609281212380.3952@g5.osdl.org>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0609281212380.3952%40g5.osdl.org
In-Reply-To: <Pine.LNX.4.64.0609281211260.3952@g5.osdl.org>

```

You can now say "5:35 PM yesterday", and approxidate() gets the right answer.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---

Useful? Of course. In a sick and twisted sort of way.

Try to say "yesterday at 5 PM" before and after this. It _really_ was 
confused before.

diff --git a/date.c b/date.c
index 4ff6604..db4c185 100644
--- a/date.c
+++ b/date.c
@@ -598,6 +598,32 @@ static void date_tea(struct tm *tm, int 
 	date_time(tm, 17);
 }
 
+static void date_pm(struct tm *tm, int *num)
+{
+	int hour = *num;
+	*num = 0;
+
+	if (hour > 0 && hour < 12) {
+		tm->tm_hour = hour;
+		tm->tm_min = 0;
+		tm->tm_sec = 0;
+	}
+	if (tm->tm_hour > 0 && tm->tm_hour < 12)
+		tm->tm_hour += 12;
+}
+
+static void date_am(struct tm *tm, int *num)
+{
+	int hour = *num;
+	*num = 0;
+
+	if (hour > 0 && hour < 12) {
+		tm->tm_hour = hour;
+		tm->tm_min = 0;
+		tm->tm_sec = 0;
+	}
+}
+
 static const struct special {
 	const char *name;
 	void (*fn)(struct tm *, int *);
@@ -606,6 +632,8 @@ static const struct special {
 	{ "noon", date_noon },
 	{ "midnight", date_midnight },
 	{ "tea", date_tea },
+	{ "PM", date_pm },
+	{ "AM", date_am },
 	{ NULL }
 };
 
@@ -717,6 +745,18 @@ static const char *approxidate_digit(con
 	char *end;
 	unsigned long number = strtoul(date, &end, 10);
 
+	switch (*end) {
+	case ':':
+	case '.':
+	case '/':
+	case '-':
+		if (isdigit(end[1])) {
+			int match = match_multi_number(number, *end, date, end, tm);
+			if (match)
+				return date + match;
+		}
+	}
+
 	*num = number;
 	return end;
 }

```

## Morten Welinder, 2006-09-29 00:12

Subject: Re: Fix approxidate() to understand more extended numbers
Message-ID: <118833cc0609281712u2ce01bc5r8f3e97ae9c9a749a@mail.gmail.com>
URL: https://gitlist.dev/e/118833cc0609281712u2ce01bc5r8f3e97ae9c9a749a%40mail.gmail.com
In-Reply-To: <Pine.LNX.4.64.0609281212380.3952@g5.osdl.org>

```
Just don't hack at 12am or 12pm.

M.

```

## Linus Torvalds, 2006-09-29 06:03

Subject: Re: Fix approxidate() to understand more extended numbers
Message-ID: <Pine.LNX.4.64.0609282300190.3952@g5.osdl.org>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0609282300190.3952%40g5.osdl.org
In-Reply-To: <118833cc0609281712u2ce01bc5r8f3e97ae9c9a749a@mail.gmail.com>

```


On Thu, 28 Sep 2006, Morten Welinder wrote:
>
> Just don't hack at 12am or 12pm.

I think 12pm is correct, but 12am probably isn't (12am should _subtract_ 
12, while 12pm does _not_ add 12).

That said, I have a rice cooker that avoids the problem by saying "0:10 PM" 
for ten minutes past midday ;)

Of course, all sane and civilized countries just use 24-hour format 
anyway. "Military time" my *ss. 

Some day the US will turn metric and 24-hour-format. If the sun doesn't 
turn into a red giant first, that is.

		Linus

```

## Junio C Hamano, 2006-09-29 06:14

Subject: Re: Fix approxidate() to understand more extended numbers
Message-ID: <7vd59fp5b9.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7vd59fp5b9.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <Pine.LNX.4.64.0609282300190.3952@g5.osdl.org>

```
Linus Torvalds <torvalds@osdl.org> writes:

> On Thu, 28 Sep 2006, Morten Welinder wrote:
>>
>> Just don't hack at 12am or 12pm.
>
> I think 12pm is correct, but 12am probably isn't (12am should _subtract_ 
> 12, while 12pm does _not_ add 12).

But you have "if (hour > 0 && hour < 12)" in both am and pm so
assignment to tm would not trigger...

> That said, I have a rice cooker that avoids the problem by saying "0:10 PM" 
> for ten minutes past midday ;)

You eat rice?

> Of course, all sane and civilized countries just use 24-hour format 
> anyway.

You are referring to the US, but neither is Japan sane nor
civilized ;-).

```

## Linus Torvalds, 2006-09-29 06:42

Subject: Re: Fix approxidate() to understand more extended numbers
Message-ID: <Pine.LNX.4.64.0609282330440.3952@g5.osdl.org>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0609282330440.3952%40g5.osdl.org
In-Reply-To: <7vd59fp5b9.fsf@assigned-by-dhcp.cox.net>

```


On Thu, 28 Sep 2006, Junio C Hamano wrote:

> Linus Torvalds <torvalds@osdl.org> writes:
> 
> > On Thu, 28 Sep 2006, Morten Welinder wrote:
> >>
> >> Just don't hack at 12am or 12pm.
> >
> > I think 12pm is correct, but 12am probably isn't (12am should _subtract_ 
> > 12, while 12pm does _not_ add 12).
> 
> But you have "if (hour > 0 && hour < 12)" in both am and pm so
> assignment to tm would not trigger...

That's not the point.

If you write

	12:30 am

you really _should_ subtract 12, leaving you with 0:30. We don't. So we 
end up with a 24-hour time of 12:30, which is obviously _pm_, and wrong.

And "12 am" or "12 pm" doesn't work at all.

> > That said, I have a rice cooker that avoids the problem by saying "0:10 PM" 
> > for ten minutes past midday ;)
> 
> You eat rice?

Ok, is it just me, or is that just a very odd question?

I can see the question "You eat uni?". That really _does_ take a bit of 
getting used to. And Natto I really _really_ don't see the point of. 

But rice? Afaik, it's the most common food-staple in the world. It's not 
exactly odd and exotic..

> > Of course, all sane and civilized countries just use 24-hour format 
> > anyway.
> 
> You are referring to the US, but neither is Japan sane nor
> civilized ;-).

Yeah, well, they've been learning bad habits. But at least they are 
metric.

		Linus

```

## Junio C Hamano, 2006-09-29 07:09

Subject: Re: Fix approxidate() to understand more extended numbers
Message-ID: <7vslibno88.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7vslibno88.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <Pine.LNX.4.64.0609282330440.3952@g5.osdl.org>

```
Linus Torvalds <torvalds@osdl.org> writes:

>> > I think 12pm is correct, but 12am probably isn't (12am should _subtract_ 
>> > 12, while 12pm does _not_ add 12).
>> 
>> But you have "if (hour > 0 && hour < 12)" in both am and pm so
>> assignment to tm would not trigger...
>
> That's not the point.
>
> If you write
>
> 	12:30 am
>
> you really _should_ subtract 12, leaving you with 0:30. We don't. So we 
> end up with a 24-hour time of 12:30, which is obviously _pm_, and wrong.
>
> And "12 am" or "12 pm" doesn't work at all.

Ah, that's what you meant.  My brain a bit too tired from the
day job tonight X-<.

>> > That said, I have a rice cooker that avoids the problem by saying "0:10 PM" 
>> > for ten minutes past midday ;)
>> 
>> You eat rice?
>
> Ok, is it just me, or is that just a very odd question?

Having rice cooker implied eating the stuff regularly and I just
did not expect that from a north european.  Just showing my
ignorance -- I've never been to Europe.

```

## Johannes Schindelin, 2006-09-29 14:04

Subject: Re: Fix approxidate() to understand more extended numbers
Message-ID: <Pine.LNX.4.63.0609291602200.14200@wbgn013.biozentrum.uni-wuerzburg.de>
URL: https://gitlist.dev/e/Pine.LNX.4.63.0609291602200.14200%40wbgn013.biozentrum.uni-wuerzburg.de
In-Reply-To: <7vslibno88.fsf@assigned-by-dhcp.cox.net>

```
Hi,

On Fri, 29 Sep 2006, Junio C Hamano wrote:

> Having rice cooker implied eating the stuff regularly and I just
> did not expect that from a north european.  Just showing my
> ignorance -- I've never been to Europe.

Actually, yesterday I saw a digital wrist watch for the first time in my 
life! Amazing! ;-)

There is even a running joke about Great Britain: "Oh yes, I _love_ 
English dishes; especially the Chinese ones!"

Ciao,
Dscho

```

## Linus Torvalds, 2006-09-29 19:36

Subject: Re: Fix approxidate() to understand more extended numbers
Message-ID: <Pine.LNX.4.64.0609291231560.3952@g5.osdl.org>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0609291231560.3952%40g5.osdl.org
In-Reply-To: <7vslibno88.fsf@assigned-by-dhcp.cox.net>

```


On Fri, 29 Sep 2006, Junio C Hamano wrote:
> Linus Torvalds <torvalds@osdl.org> writes:
> >
> > If you write
> >
> > 	12:30 am
> >
> > you really _should_ subtract 12, leaving you with 0:30. We don't. So we 
> > end up with a 24-hour time of 12:30, which is obviously _pm_, and wrong.
> >
> > And "12 am" or "12 pm" doesn't work at all.
> 
> Ah, that's what you meant.  My brain a bit too tired from the
> day job tonight X-<.

Here's a patch that should work. It just simplifies the whole thing to say 

	"hour = (hour % 12) + X"

where X is 12 for PM and 0 for AM.

It also fixes the "exact date" parsing, which didn't parse AM at all, and 
as such would do the same "12:30 AM" means "12:30 24-hour-format" bug. Of 
course, I hope that no exact dates use AM/PM anyway, but since we support 
the PM format, let's just get it right.

Not hugely tested, but I did test some of it, and it all _looks_ sane.

		Linus
---
diff --git a/date.c b/date.c
index db4c185..1825922 100644
--- a/date.c
+++ b/date.c
@@ -256,8 +256,12 @@ static int match_alpha(const char *date,
 	}
 
 	if (match_string(date, "PM") == 2) {
-		if (tm->tm_hour > 0 && tm->tm_hour < 12)
-			tm->tm_hour += 12;
+		tm->tm_hour = (tm->tm_hour % 12) + 12;
+		return 2;
+	}
+
+	if (match_string(date, "AM") == 2) {
+		tm->tm_hour = (tm->tm_hour % 12) + 0;
 		return 2;
 	}
 
@@ -600,28 +604,30 @@ static void date_tea(struct tm *tm, int 
 
 static void date_pm(struct tm *tm, int *num)
 {
-	int hour = *num;
+	int hour, n = *num;
 	*num = 0;
 
-	if (hour > 0 && hour < 12) {
-		tm->tm_hour = hour;
+	hour = tm->tm_hour;
+	if (n) {
+		hour = n;
 		tm->tm_min = 0;
 		tm->tm_sec = 0;
 	}
-	if (tm->tm_hour > 0 && tm->tm_hour < 12)
-		tm->tm_hour += 12;
+	tm->tm_hour = (hour % 12) + 12;
 }
 
 static void date_am(struct tm *tm, int *num)
 {
-	int hour = *num;
+	int hour, n = *num;
 	*num = 0;
 
-	if (hour > 0 && hour < 12) {
-		tm->tm_hour = hour;
+	hour = tm->tm_hour;
+	if (n) {
+		hour = n;
 		tm->tm_min = 0;
 		tm->tm_sec = 0;
 	}
+	tm->tm_hour = (hour % 12);
 }
 
 static const struct special {

```
