diff src/util.c @ 127:3c71e28c8eef noffle

[svn] Release-1-0 mergedocs/NOTES
author bears
date Tue, 25 Jul 2000 13:14:54 +0100
parents 2bedacfe1ba7
children 94f2e5607772
line wrap: on
line diff
--- a/src/util.c	Tue Jul 25 13:12:50 2000 +0100
+++ b/src/util.c	Tue Jul 25 13:14:54 2000 +0100
@@ -1,7 +1,7 @@
 /*
   util.c
 
-  $Id: util.c 149 2000-06-19 21:56:12Z bears $
+  $Id: util.c 183 2000-07-25 12:14:54Z bears $
 */
 
 #if HAVE_CONFIG_H
@@ -265,31 +265,75 @@
 static const char *MON[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
 			     "Aug", "Sep", "Oct", "Nov", "Dec", NULL };
 
+/*
+ * Calculate the difference between local time and GMT. This is INN's
+ * 'always-works' method. It assumes the time differences is < 24hrs.
+ * Sounds reasonable to me. It also assumes it can ignore seconds.
+ * Returns GMT - localtime minutes. It will also trash the localtime/
+ * gmtime/etc. static buffer.
+ */
+static int
+tzDiff( void )
+{
+    time_t now;
+    struct tm local, gmt, *tm;
+    static time_t nextCalc = 0;
+    static int res = 0;
+
+    now = time( NULL );
+    if ( now < nextCalc )
+	return res;
+    
+    tm = localtime( &now );
+    if ( tm == NULL )
+	return 0;
+    local = *tm;
+    tm = gmtime( &now );
+    if ( tm == NULL )
+	return 0;
+    gmt = *tm;
+
+    res = gmt.tm_yday - local.tm_yday;
+    if ( res < -1 )
+	res = -1;		/* Year rollover? */
+    else if ( res > 1 )
+	res = 1;
+
+    res *= 24;
+    res += gmt.tm_hour - local.tm_hour;
+    res *= 60;
+    res += gmt.tm_min - local.tm_min;
+
+    /* Need to recalc at start of next hour */
+    nextCalc = now + ( 60 - local.tm_sec ) + 60 * ( 59 - local.tm_min );
+    
+    return res;
+}
+
 void
 Utl_newsDate( time_t t, Str res )
 {    
-    struct tm local, localAsGmt;
-    time_t tlocalAsGmt;
-    int tzdiff, hoffset, moffset;
+    struct tm *local;
+    long tzdiff, hoffset, moffset;
+
+    tzdiff = - tzDiff();
 
-    local = *localtime( &t );
-    memset( &localAsGmt, 0, sizeof( localAsGmt ) );
-    localAsGmt.tm_sec = local.tm_sec;
-    localAsGmt.tm_min = local.tm_min;
-    localAsGmt.tm_hour = local.tm_hour;
-    localAsGmt.tm_mday = local.tm_mday;
-    localAsGmt.tm_mon = local.tm_mon;
-    localAsGmt.tm_year = local.tm_year;
-    tlocalAsGmt = mktime( &localAsGmt );
-    tzdiff = (int) ( ( (long) difftime( tlocalAsGmt, t ) ) / 60 );
+    local = localtime( &t );
+    if ( local == NULL )
+    {
+	Utl_cpyStr( res, "** localtime failure **" );
+	return;
+    }
+    
     hoffset = tzdiff / 60;
     moffset = tzdiff % 60;
-    if ( moffset < 0 ) moffset = -moffset;
+    if ( moffset < 0 )
+	moffset = - moffset;
 
-    sprintf( res, "%s, %d %s %4d %02d:%02d:%02d %+03d%02d",
-	     DOTW[local.tm_wday], local.tm_mday,
-	     MON[local.tm_mon], local.tm_year + 1900,
-	     local.tm_hour, local.tm_min, local.tm_sec,
+    sprintf( res, "%s, %d %s %4d %02d:%02d:%02d %+03ld%02ld",
+	     DOTW[local->tm_wday], local->tm_mday,
+	     MON[local->tm_mon], local->tm_year + 1900,
+	     local->tm_hour, local->tm_min, local->tm_sec,
 	     hoffset, moffset );
 }
 
@@ -297,12 +341,13 @@
 Utl_parseNewsDate( const char *s )
 {
     struct tm tm;
-    int wday, tzoffset, hoffset, moffset;
+    int wday, offset, tzoffset;
     char *p;
     time_t res;
 
     memset( &tm, 0, sizeof( tm ) );
     wday = -1;
+    tm.tm_isdst = -1;
     
     s = nextNonWhiteSpace( s );
 
@@ -380,8 +425,9 @@
 	s += 2;
     else
     {
-	tzoffset = (int) strtol( s, &p, 10 );
+	offset = (int) strtol( s, &p, 10 );
 	s = p;
+	tzoffset = ( offset / 100 ) * 60 + ( offset % 100 );
     }
 
     /* Check for following junk */
@@ -395,9 +441,12 @@
     if ( wday >= 0 && wday != tm.tm_wday )
 	return (time_t) -1;
 
-    moffset = tzoffset % 100;
-    hoffset = tzoffset / 100;
-    res = res - ( ( hoffset * 60 + moffset ) * 60 );
+    /* Remove local time diff from res to give time as if GMT */
+    res -= tzDiff() * 60;
+
+    /* And now adjust for tzoffset */
+    res -= tzoffset * 60;
+    
     return res;
 }
 
@@ -429,7 +478,9 @@
 
     for ( ; ; )
     {
-	printf( "\nEnter date:  " );
+	t = time( NULL );
+	Utl_newsDate( t, line );
+	printf( "\n(%s) Enter date:  ", line );
 	(void) fflush( stdout );
 	if ( gets( line ) == NULL || line[0] == '\0' )
 	    break;
@@ -440,8 +491,7 @@
 	else
 	{
 	    Utl_newsDate( t, line );
-	    printf( "Utl_newsDate -> '%s'\nctime() -> '%s'\n",
-		    line, ctime( &t ) );
+	    printf( "Utl_newsDate -> '%s'\n", line );
 	}
     }