Re: Trying to use AUTHOR_DATE

7 messages, 4 authors, 2016-06-15 · open the first message on its own page

Re: Trying to use AUTHOR_DATE

From: Russ Allbery <hidden>
Date: 2016-06-15 22:41:55

Edgar Toernig [off-list ref] writes:
Oh btw, when we are about sucking time functions: the %s and %z
strftime- sequences used further down are also non-standard (POSIX has
no %s, old libc has neither %s nor %z).
A possible workaround:
[...]
	tm = localtime(&now); /* get timezone and tm_isdst */
	tz = -timezone / 60;
	if (tm->tm_isdst > 0)
		tz += 60;
The global timezone variable isn't available on all systems.  :)

You really cannot get portable behavior in this area without something
akin to Autoconf probes, unfortunately.  Oh, and you can't assume daylight
savings time is an hour; it is sometimes two hours.  You have to instead
use the altzone variable to get the offset when you're in daylight savings
time, but this again isn't available on all systems.

I posted a pointer to the INN source a while back; I'm really not sure
that anything less is sufficient to get full portability, although I
certainly trust Paul Eggart's implementation.

BTW, the yacc-based thing is exactly what I wrote the INN code to get rid
of, since I didn't want a yacc dependency.

-- 
Russ Allbery (rra@stanford.edu)             <http://www.eyrie.org/~eagle/>

Re: Trying to use AUTHOR_DATE

From: Linus Torvalds <torvalds@osdl.org>
Date: 2016-06-15 22:41:55


On Sat, 30 Apr 2005, Russ Allbery wrote:
You really cannot get portable behavior in this area without something
akin to Autoconf probes, unfortunately. 
Ok, since this only really matters for AUTHOR_DATE, which we pass in as a
random string anyway, and which comes from various mail programs which may
or may not follow all RFC's, I just rewrote it to give "almost correct 
results" for "pretty much any crap you throw at it".

As a test-bed, a "test-date" program that parses a date and then prints 
it out in git format _and_ in the local timezone format, here's a few 
examples:

	./test-date "$(date)" "April 4th, 1992 at 13:45" "13:04:09 +0100 2004 Yesterday, Friday 13th, December"

results in

	Sat Apr 30 13:26:52 PDT 2005 -> 1114892812 -0700 -> Sat Apr 30 13:26:52 2005

	April 4th, 1992 at 13:45 -> 702395100 +0000 -> Sat Apr  4 05:45:00 1992

	13:04:09 +0100 2004 Yesterday, Friday 13th, December -> 1102939449 +0100 -> Mon Dec 13 04:04:09 2004

which is just because it really doesn't check a hell of a lot.

For example, if you say

	"I caught 14 fishes in December 1998"

test-date will happily parse this as

	Sun Dec 13 16:00:00 1998

(That's "0:00:00 Dec 14th, 1998 UTC" shown in the local timezone ;). Or:

	./test-date  "12:15 4/17/2009"

	12:15 4/17/2009 -> 1239970500 +0000 -> Fri Apr 17 05:15:00 2009

ie it just greedily tries to make _some_ sense of the random strings you 
throw at it.

It doesn't even try getting timezones right - it doesn't know about 
summertime or anything. Besides, I probably used the wrong timezone info 
anyway.

I'll probably tweak it a bit more (make "no timezone means local 
timezone", for example, rather than UTC like it is now).

		Linus

Re: Trying to use AUTHOR_DATE

From: Edgar Toernig <hidden>
Date: 2016-06-15 22:41:55

Linus Torvalds wrote:
[...] I just rewrote it to give "almost correct 
results" for "pretty much any crap you throw at it".
And I had the impression the strict checks in the original
version were intentionally ;-)
I'll probably tweak it a bit more (make "no timezone means local 
timezone", for example, rather than UTC like it is now).
Here's my try on that.  But whether it works everywhere ...

Btw, your %+03d%02d printf gave wrong results for i.e. -0130 (-01-30).


--- k/date.c  (mode:100644)
+++ l/date.c  (mode:100644)
@@ -10,7 +10,9 @@
 #include <ctype.h>
 #include <time.h>
 
-static time_t my_mktime(struct tm *tm)
+#define NO_TZ	11111
+
+static time_t utc_mktime(struct tm *tm)
 {
 	static const int mdays[] = {
 	    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
@@ -23,12 +25,19 @@ static time_t my_mktime(struct tm *tm)
 		return -1;
 	if (month < 0 || month > 11) /* array bounds */
 		return -1;
+	if (day < 1 || day > 31)
+		return -1;
 	if (month < 2 || (year + 2) % 4)
 		day--;
 	return (year * 365 + (year + 1) / 4 + mdays[month] + day) * 24*60*60UL +
 		tm->tm_hour * 60*60 + tm->tm_min * 60 + tm->tm_sec;
 }
 
+static int local_offset(time_t *when)
+{
+	return (utc_mktime(localtime(when)) - *when) / 60;
+}
+
 static const char *month_names[] = {
 	"January", "February", "March", "April", "May", "June",
 	"July", "August", "September", "October", "November", "December"
@@ -138,7 +147,8 @@ static int match_alpha(const char *date,
 	for (i = 0; i < NR_TZ; i++) {
 		int match = match_string(date, timezone_names[i].name);
 		if (match >= 3) {
-			*offset = 60*timezone_names[i].offset;
+			if (*offset == NO_TZ)
+				*offset = 60*timezone_names[i].offset;
 			return match;
 		}
 	}
@@ -245,7 +255,7 @@ void parse_date(char *date, char *result
 	tm.tm_year = -1;
 	tm.tm_mon = -1;
 	tm.tm_mday = -1;
-	offset = 0;
+	offset = NO_TZ;
 
 	for (;;) {
 		int match = 0;
@@ -270,13 +280,20 @@ void parse_date(char *date, char *result
 		date += match;
 	}
 
-	then = my_mktime(&tm); /* mktime uses local timezone */
-	if (then == -1)
-		return;
-
-	then -= offset * 60;
+	if (offset == NO_TZ) {
+		tm.tm_isdst = -1;
+		then = mktime(&tm);
+		if (then == -1)
+			return;
+		offset = local_offset(&then);
+	} else {
+		then = utc_mktime(&tm);
+		if (then == -1)
+			return;
+		then -= offset * 60;
+	}
 
-	snprintf(result, maxlen, "%lu %+03d%02d", then, offset/60, offset % 60);
+	snprintf(result, maxlen, "%lu %+05d", then, offset/60*100 + offset%60);
 }
 
 void datestamp(char *buf, int bufsize)
@@ -285,9 +302,7 @@ void datestamp(char *buf, int bufsize)
 	int offset;
 
 	time(&now);
-
-	offset = my_mktime(localtime(&now)) - now;
-	offset /= 60;
+	offset = local_offset(&now);
 
 	snprintf(buf, bufsize, "%lu %+05d", now, offset/60*100 + offset%60);
 }
Ciao, ET.

Re: Trying to use AUTHOR_DATE

From: Linus Torvalds <torvalds@osdl.org>
Date: 2016-06-15 22:41:55


On Sun, 1 May 2005, Edgar Toernig wrote:
quoted
I'll probably tweak it a bit more (make "no timezone means local 
timezone", for example, rather than UTC like it is now).
Here's my try on that.  But whether it works everywhere ...
I already did that part.
Btw, your %+03d%02d printf gave wrong results for i.e. -0130 (-01-30).
Dang. Oh, well. That's what I get for not testing.

I don't much like that "%+05s" trick either, since that one also depends 
on the direction of rounding for negative division (it just gets it right 
for the normal case, and I guess C90 finally specified it precisely).

Let's just do unsigned arithmetic and check the sign specially. I already 
did that on input, just not on output.

		Linus

Re: Trying to use AUTHOR_DATE

From: Linus Torvalds <torvalds@osdl.org>
Date: 2016-06-15 22:41:55


On Sun, 1 May 2005, Edgar Toernig wrote:
And I had the impression the strict checks in the original
version were intentionally ;-)
Btw, here's my test of every single email in my email archive (which is 
not that big any more - after the SCO subpoena, I decided that I never 
want to go through with that kind of crap ever again, so now it's only a 
month or two of things). 

Almost everything seems to follow the RFC's or at least be close enough
that my "accept anything" ends up doing something sane, except for three
emails:

	Date: Fri, 08 Apr 2005 02:20:10 0200 -> bad
	Date: Mon, 18 Apr 05 15:05:29 Hora oficial do Brasil -> bad
	Date: 2002/04/11 18:29:07 -> bad

That first one doesn't have a sign in front of the timezone (I'll fix
things up - right now I end up believing that it's "year 200"), and the
third one has the sane European date order that sorts nicely (and which
I'll also fix up).

The second one is funny. Not just the "Hora oficial do Brasil" (hey, I 
could add it as a real timezone and my parser would do the right thing ;) 
but also because my parser decides that "05" is not a year, but the day in 
the month, so it doesn't see the year.

I can fake out that year thing pretty easily ("if it starts with '0' it's 
not a day of the month"), but it does show just how _strange_ stuff 
there's out there.

("Hora" is also Swedish for "whore", so that timezone does end up being
mentally parsed _quite_ the wrong way for somebody like me who doesn't
speak spanish).

			Linus

Re: Trying to use AUTHOR_DATE

From: Randy.Dunlap <hidden>
Date: 2016-06-15 22:41:55

On Sun, 1 May 2005 09:46:52 -0700 (PDT) Linus Torvalds wrote:

| 
| 
| On Sun, 1 May 2005, Edgar Toernig wrote:
| > 
| > And I had the impression the strict checks in the original
| > version were intentionally ;-)
| 
| Btw, here's my test of every single email in my email archive (which is 
| not that big any more - after the SCO subpoena, I decided that I never 
| want to go through with that kind of crap ever again, so now it's only a 
| month or two of things). 
| 
| Almost everything seems to follow the RFC's or at least be close enough
| that my "accept anything" ends up doing something sane, except for three
| emails:
| 
| 	Date: Fri, 08 Apr 2005 02:20:10 0200 -> bad
| 	Date: Mon, 18 Apr 05 15:05:29 Hora oficial do Brasil -> bad
| 	Date: 2002/04/11 18:29:07 -> bad
| 
| That first one doesn't have a sign in front of the timezone (I'll fix
| things up - right now I end up believing that it's "year 200"), and the
| third one has the sane European date order that sorts nicely (and which
| I'll also fix up).

Third one is almost ISO 8601 standard date format, except that
ISO uses hyphens, e.g., 2002-04-11, so I hope that the
punctation is a little flexible...

| The second one is funny. Not just the "Hora oficial do Brasil" (hey, I 
| could add it as a real timezone and my parser would do the right thing ;) 
| but also because my parser decides that "05" is not a year, but the day in 
| the month, so it doesn't see the year.
| 
| I can fake out that year thing pretty easily ("if it starts with '0' it's 
| not a day of the month"), but it does show just how _strange_ stuff 
| there's out there.
| 
| ("Hora" is also Swedish for "whore", so that timezone does end up being
| mentally parsed _quite_ the wrong way for somebody like me who doesn't
| speak spanish).


---
~Randy

Re: Trying to use AUTHOR_DATE

From: Edgar Toernig <hidden>
Date: 2016-06-15 22:41:55

Linus Torvalds wrote:
	Date: Fri, 08 Apr 2005 02:20:10 0200 -> bad
	Date: Mon, 18 Apr 05 15:05:29 Hora oficial do Brasil -> bad
	Date: 2002/04/11 18:29:07 -> bad

The second one is funny. Not just the "Hora oficial do Brasil" (hey, I 
could add it as a real timezone and my parser would do the right thing ;) 
but also because my parser decides that "05" is not a year, but the day in 
the month, so it doesn't see the year.

I can fake out that year thing pretty easily ("if it starts with '0' it's 
not a day of the month"), but it does show just how _strange_ stuff 
there's out there.
And what happens then with the first example?  2008 Apr 2005?


I thought about missing timezones once more.  Don't you think it's
better to default to -0000?  Afaics, it was defined for just these
cases.  Simply appending an arbitrary timezone seems wrong.

Ciao, ET.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help