Mercurial > noffle
changeset 91:93cc929329eb noffle
[svn] Date output change and now date parsing
author | bears |
---|---|
date | Fri, 19 May 2000 16:12:45 +0100 |
parents | 9cf0d605465a |
children | 160a0af71cf8 |
files | src/util.c src/util.h |
diffstat | 2 files changed, 188 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/util.c Fri May 19 08:59:51 2000 +0100 +++ b/src/util.c Fri May 19 16:12:45 2000 +0100 @@ -1,7 +1,7 @@ /* util.c - $Id: util.c 99 2000-05-18 12:11:05Z bears $ + $Id: util.c 110 2000-05-19 15:12:45Z bears $ */ #if HAVE_CONFIG_H @@ -25,12 +25,18 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#include <stdlib.h> #include <unistd.h> #include "configfile.h" #include "log.h" #include "wildmat.h" #include "portable.h" +#if defined(UTIL_TEST) +#define Log_err printf +#define Log_dbg printf +#endif + static const char * nextWhiteSpace( const char *p ) { @@ -254,10 +260,145 @@ return TRUE; } +static const char *DOTW[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", + "Sat", NULL }; +static const char *MON[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", + "Aug", "Sep", "Oct", "Nov", "Dec", NULL }; + void -Utl_rfc822Date( time_t t, Str res ) +Utl_newsDate( time_t t, Str res ) +{ + struct tm local, localAsGmt; + time_t tlocalAsGmt; + int tzdiff, hoffset, moffset; + + 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 ); + hoffset = tzdiff / 60; + moffset = tzdiff % 60; + 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, + hoffset, moffset ); +} + +time_t +Utl_parseNewsDate( const char *s ) { - strftime( res, MAXCHAR,"%a, %d %b %Y %H:%M:%S %z", localtime( &t ) ); + struct tm tm; + int wday, tzoffset, hoffset, moffset; + char *p; + time_t res; + + memset( &tm, 0, sizeof( tm ) ); + wday = -1; + + s = nextNonWhiteSpace( s ); + + /* Is this the day number, or a weekday? */ + if ( ! isdigit( *s ) ) + { + if ( strlen( s ) < 4 ) + return (time_t) -1; + + for ( wday = 0; DOTW[ wday ] != NULL; wday++ ) + if ( strncmp( DOTW[ wday ], s, 3 ) == 0 ) + break; + + if( DOTW[ wday ] == NULL || s[3] != ',' ) + return (time_t) -1; + + s += 4; + } + + /* Get the day number */ + tm.tm_mday = (int) strtol( s, &p, 10 ); + if ( p == s ) + return (time_t) -1; + s = p; + + /* Look for month name */ + s = nextNonWhiteSpace( s ); + if ( strlen( s ) < 4 ) + return (time_t) -1; + for ( tm.tm_mon = 0; MON[ tm.tm_mon ] != NULL; tm.tm_mon++ ) + if ( strncmp( MON[ tm.tm_mon ], s, 3 ) == 0 ) + break; + + if ( MON[ tm.tm_mon ] == NULL ) + return (time_t) -1; + s += 3; + + /* Year next */ + tm.tm_year = (int) strtol( s, &p, 10 ); + if ( p == s || ( tm.tm_year >= 100 && tm.tm_year < 1900 ) ) + return (time_t) -1; + if ( tm.tm_year >= 1900 ) + tm.tm_year -= 1900; + s = p; + + /* Hours */ + tm.tm_hour = (int) strtol( s, &p, 10 ); + if ( p == s || *p != ':' ) + return (time_t) -1; + s = ++p; + + /* Minutes */ + tm.tm_min = (int) strtol( s, &p, 10 ); + if ( p == s || ( *p != ':' && *p != ' ' ) ) + return (time_t) -1; + s = p; + + /* Seconds */ + if ( *s == ':' ) + { + s++; + tm.tm_sec = (int) strtol( s, &p, 10 ); + if ( p == s ) + return (time_t) -1; + s = p; + } + + /* GMT/UT or timezone offset */ + tzoffset = 0; + while ( isspace( *s ) ) + s++; + if ( strncmp( s, "GMT", 3) == 0 ) + s += 3; + else if ( strncmp( s, "UT", 2 ) == 0 ) + s += 2; + else + { + tzoffset = (int) strtol( s, &p, 10 ); + s = p; + } + + /* Check for following junk */ + if ( *s != '\0' && ! isspace( *s ) ) + return (time_t) -1; + + res = mktime( &tm ); + if ( res == (time_t) -1 ) + return res; + + if ( wday >= 0 && wday != tm.tm_wday ) + return (time_t) -1; + + moffset = tzoffset % 100; + hoffset = tzoffset / 100; + res = res - ( ( hoffset * 60 + moffset ) * 60 ); + return res; } void @@ -271,3 +412,40 @@ } memcpy( *dst, src, (size_t)len + 1 ); } + +#if defined(UTIL_TEST) + +/* Test code borrowed from wildmat.c. Yep, still uses gets(). */ +extern char *gets(); + +int +main() +{ + Str line; + time_t t; + + printf( "Util date tester. Enter date to test.\n" ); + printf( "A blank line exits the program.\n" ); + + for ( ; ; ) + { + printf( "\nEnter date: " ); + (void) fflush( stdout ); + if ( gets( line ) == NULL || line[0] == '\0' ) + break; + + t = Utl_parseNewsDate( line ); + if ( t == (time_t) -1 ) + printf( "Date parse failed\n" ); + else + { + Utl_newsDate( t, line ); + printf( "Utl_newsDate -> '%s'\nctime() -> '%s'\n", + line, ctime( &t ) ); + } + } + + exit(0); + /* NOTREACHED */ +} +#endif
--- a/src/util.h Fri May 19 08:59:51 2000 +0100 +++ b/src/util.h Fri May 19 16:12:45 2000 +0100 @@ -3,7 +3,7 @@ Miscellaneous helper functions. - $Id: util.h 99 2000-05-18 12:11:05Z bears $ + $Id: util.h 110 2000-05-19 15:12:45Z bears $ */ #ifndef UTL_H @@ -76,9 +76,13 @@ Bool Utl_getStamp( time_t *result, Str file ); -/* Put RFC822-compliant date string into res. */ +/* Put SonOfRFC1036 compliant date string into res. */ void -Utl_rfc822Date( time_t t, Str res ); +Utl_newsDate( time_t t, Str res ); + +/* Attempt to parse a SonOfRFC1036 compliant date string. Return -1 on fail. */ +time_t +Utl_parseNewsDate( const char *s ); void Utl_cpyStr( Str dst, const char *src );