tz
Threads by month
- ----- 2026 -----
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1999 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1998 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1997 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1996 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1995 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1994 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1993 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1992 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1991 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1990 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1989 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1988 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1987 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1986 -----
- December
- November
- 10 participants
- 7500 discussions
Feb. 21, 1995
Newsgroups: alt.sources
From: jef(a)netcom.com (Jef Poskanzer)
Subject: date_parse - simple date parsing routine and programs
Message-ID: <jefD3uzqC.Mos(a)netcom.com>
Reply-To: Jef Poskanzer <jef(a)netcom.com>
Organization: Paratheo-Anametamystikhood Of Eris Esoteric
Date: Sat, 11 Feb 1995 23:25:24 GMT
Lines: 2048
Sender: jef(a)netcom18.netcom.com
date_parse - date parsing routine and programs
version 1.0 of 11feb95
For a while now I've been somewhat unhappy with the various
date-parsing routines available - yacc-based, lex-based, ad-hoc. Large
code size and not very portable are the main complaints. So I wrote a
new one that just does a bunch of sscanf's until one matches. Slow,
but small and portable. To figure out what formats to support I did a
survey of Date: lines in a bunch of Usenet articles. The following two
formats accounted for more than 99% of all articles:
N mth YYYY HH:MM:SS ampm zone
wdy, N mth YYYY HH:MM:SS ampm zone
I added Unix ctime() format and a few others:
wdy mth N HH:MM:SS ampm zone YYYY
HH:MM:SS ampm zone N mth YYYY
N mth YYYY
HH:MM:SS ampm
No-zone, no-seconds, and no-am/pm versions of each are also supported.
Note that dd/mm/yy and mm/dd/yy are NOT supported - those formats are
dumb.
Aside from the date-parsing routine, this package includes some programs
that exercise it:
o date_sort - sort a file's lines by date
o date_order - order a list of files by netnews/mail-format Date: lines
o deltime - subtract two times and show the difference
o xmit_time - figure transmission time of netnews articles
- - - - - - - - - -
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# Makefile
# README
# ctime.c
# date_order.1
# date_order.c
# date_parse.3
# date_parse.c
# date_sort.1
# date_sort.c
# deltime.1
# deltime.c
# dptest.c
# test_input
# test_output
# xmit_time.1
# xmit_time.c
# This archive created: Sat Feb 11 15:21:30 1995
# By: Jef Poskanzer
export PATH; PATH=/bin:$PATH
echo shar: extracting "'Makefile'" '(1873 characters)'
if test -f 'Makefile'
then
echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
X# Makefile for date_parse and friends
X
X# CONFIGURE: the directory where you want the library installed
XLIBDIR = /usr/local/lib
X
X# CONFIGURE: the directory where you want the executables installed
XBINDIR = /usr/local/bin
X
X# CONFIGURE: the directory tree where you want the man pages installed
XMANDIR = /usr/local/man
X
X# CONFIGURE: type of system - uncomment one of these
XDEFINES = -DBSD
X#DEFINES = -DSYSV
X
X# CONFIGURE: your compiler
X#CC = cc
XCC = gcc -ansi -pedantic
X
X# CONFIGURE: your compiler flags
XCFLAGS = -O $(DEFINES)
X#CFLAGS = -g $(DEFINES)
X#CFLAGS = $(DEFINES)
X
X# CONFIGURE: your loader flags
XLDFLAGS = -s
X#LDFLAGS =
X
X# End of configurable definitions.
X
XLIB = libdate_parse.a
XEXES = date_order date_sort deltime xmit_time
X
Xall: $(LIB) $(EXES)
X
Xlibdate_parse.a: date_parse.o
X rm -f libdate_parse.a
X ar rc libdate_parse.a date_parse.o
X -ranlib libdate_parse.a
X
Xdate_order: date_order.c $(LIB)
X $(CC) $(CFLAGS) $(LDFLAGS) date_order.c $(LIB) -o date_order
X
Xdate_sort: date_sort.c $(LIB)
X $(CC) $(CFLAGS) $(LDFLAGS) date_sort.c $(LIB) -o date_sort
X
Xdeltime: deltime.c $(LIB)
X $(CC) $(CFLAGS) $(LDFLAGS) deltime.c $(LIB) -o deltime
X
Xxmit_time: xmit_time.c $(LIB)
X $(CC) $(CFLAGS) $(LDFLAGS) xmit_time.c $(LIB) -o xmit_time
X
Xctime: ctime.c
X $(CC) $(CFLAGS) $(LDFLAGS) ctime.c -o ctime
X
X.c.o:
X $(CC) $(CFLAGS) -c $<
X
Xtest: all dptest
X ./dptest < test_input | diff test_output -
X
Xdptest: dptest.c $(LIB)
X $(CC) $(CFLAGS) $(LDFLAGS) dptest.c $(LIB) -o dptest
X
Xinstall: all
X for i in $(LIB) ; do \
X rm -f $(LIBDIR)/$$i ; \
X cp $$i $(LIBDIR) ; \
X done
X for i in $(EXES) ; do \
X rm -f $(BINDIR)/$$i ; \
X cp $$i $(BINDIR) ; \
X done
X rm -f $(MANDIR)/man3/date_parse.3
X cp date_parse.3 $(MANDIR)/man3
X for i in $(EXES) ; do \
X rm -f $(MANDIR)/man1/$$i.1 ; \
X cp $$i.1 $(MANDIR)/man1 ; \
X done
X
Xclean:
X rm -f *.o *.a $(EXES) dptest ctime a.out core
SHAR_EOF
if test 1873 -ne "`wc -c < 'Makefile'`"
then
echo shar: error transmitting "'Makefile'" '(should have been 1873
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'README'" '(1546 characters)'
if test -f 'README'
then
echo shar: will not over-write existing file "'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
X date_parse - date parsing routine and programs
X version 1.0 of 11feb95
X
XFor a while now I've been somewhat unhappy with the various
Xdate-parsing routines available - yacc-based, lex-based, ad-hoc. Large
Xcode size and not very portable are the main complaints. So I wrote a
Xnew one that just does a bunch of sscanf's until one matches. Slow,
Xbut small and portable. To figure out what formats to support I did a
Xsurvey of Date: lines in a bunch of Usenet articles. The following two
Xformats accounted for more than 99% of all articles:
X
X N mth YYYY HH:MM:SS ampm zone
X wdy, N mth YYYY HH:MM:SS ampm zone
X
XI added Unix ctime() format and a few others:
X
X wdy mth N HH:MM:SS ampm zone YYYY
X HH:MM:SS ampm zone N mth YYYY
X N mth YYYY
X HH:MM:SS ampm
X
XNo-zone, no-seconds, and no-am/pm versions of each are also supported.
XNote that dd/mm/yy and mm/dd/yy are NOT supported - those formats are
Xdumb.
X
XAside from the date-parsing routine, this package includes some programs
Xthat exercise it:
X o date_sort - sort a file's lines by date
X o date_order - order a list of files by netnews/mail-format Date: lines
X o deltime - subtract two times and show the difference
X o xmit_time - figure transmission time of netnews articles
X
XSee the manual entries for more details.
X
X
XTo install:
X Unpack the files.
X Edit the Makefile to change the configuration options if necessary.
X Make test to check that it works right.
X Make install.
X
XComments to:
X Jef Poskanzer jef(a)netcom.com jef(a)well.com
SHAR_EOF
if test 1546 -ne "`wc -c < 'README'`"
then
echo shar: error transmitting "'README'" '(should have been 1546
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ctime.c'" '(225 characters)'
if test -f 'ctime.c'
then
echo shar: will not over-write existing file "'ctime.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ctime.c'
X/* simple debugging tool */
X
X#include <stdio.h>
X#include <time.h>
X
Xvoid
Xmain( argc, argv )
X int argc;
X char* argv[];
X {
X time_t t;
X
X t = atoi( argv[1] );
X printf( "%s\n", ctime( &t ) );
X exit( 0 );
X }
SHAR_EOF
if test 225 -ne "`wc -c < 'ctime.c'`"
then
echo shar: error transmitting "'ctime.c'" '(should have been 225
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'date_order.1'" '(1535 characters)'
if test -f 'date_order.1'
then
echo shar: will not over-write existing file "'date_order.1'"
else
sed 's/^X//' << \SHAR_EOF > 'date_order.1'
X.TH date_order 1 "11 February 1995"
X.SH NAME
Xdate_order - order filenames by date
X.SH SYNOPSIS
X.B date_order
X.RI [ file
X.IR ... ]
X.SH DESCRIPTION
X.PP
XGiven a set of filenames as arguments, looks in each file for
Xan email/netnews-format Date: line and writes the filenames out again
Xsorted by the dates.
X.PP
XThis does not change or rearrange the actual files in any way.
XAll it does it produce a new list of the fileNAMEs, sorted by the dates
Xin the files.
X.PP
XThe intended use is with a shell's backquote construct.
XFor instance, if you have a version of uudecode that automatically
Xskips headers and trailers and handles multiple input and output files
X(such as my version),
Xthen you can decode the entire current contents of a picture-newsgroup spool
Xdirectory with one command:
X.nf
X uudecode `date_order *`
X.fi
XThe reason you want to use date_order instead of just doing "uudecode *"
Xis that netnews articles often arrive out of order.
XUsing date_order hands them to uudecode in the order they were posted.
X.SH "SEE ALSO"
Xdate_sort(1), deltime(1), xmit_time(1), date_parse(3), uudecode(1)
X.SH AUTHOR
XCopyright (C) 1995 by Jef Poskanzer.
X.\" Permission to use, copy, modify, and distribute this software and its
X.\" documentation for any purpose and without fee is hereby granted, provided
X.\" that the above copyright notice appear in all copies and that both that
X.\" copyright notice and this permission notice appear in supporting
X.\" documentation. This software is provided "as is" without express or
X.\" implied warranty.
SHAR_EOF
if test 1535 -ne "`wc -c < 'date_order.1'`"
then
echo shar: error transmitting "'date_order.1'" '(should have been 1535
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'date_order.c'" '(3040 characters)'
if test -f 'date_order.c'
then
echo shar: will not over-write existing file "'date_order.c'"
else
sed 's/^X//' << \SHAR_EOF > 'date_order.c'
X/* date_order - order filenames by date
X**
X** Copyright (C) 1995 by Jef Poskanzer <jef(a)netcom.com>.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation. This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include <string.h>
X#include <malloc.h>
X#include <time.h>
X
Xextern time_t date_parse();
X
Xstatic void usage();
Xstatic time_t date_file();
Xstatic int file_compare();
Xstatic char* my_malloc();
Xstatic char* my_realloc();
Xstatic void out_of_mem();
X
Xstatic char* argv0;
X
Xstruct file
X {
X char* name;
X time_t date;
X };
X
Xstatic int maxfiles, nfiles;
Xstatic struct file* files;
X
Xvoid
Xmain( argc, argv )
X int argc;
X char* argv[];
X {
X int argn;
X int i;
X
X argv0 = argv[0];
X argn = 1;
X if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
X usage();
X
X maxfiles = argc - argn;
X files = (struct file*) my_malloc( maxfiles * sizeof(struct file) );
X nfiles = 0;
X
X while ( argn < argc )
X {
X files[nfiles].name = (char*) my_malloc( strlen( argv[argn] ) + 1 );
X (void) strcpy( files[nfiles].name, argv[argn] );
X files[nfiles].date = date_file( argv[argn] );
X ++nfiles;
X ++argn;
X }
X
X qsort( files, nfiles, sizeof(struct file), file_compare );
X
X for ( i = 0; i < nfiles; ++i )
X {
X if ( i != 0 )
X putchar( ' ' );
X fputs( files[i].name, stdout );
X }
X putchar( '\n' );
X
X exit( 0 );
X }
X
Xstatic void
Xusage()
X {
X (void) fprintf( stderr, "usage: %s [file ...]\n", argv0 );
X exit( 1 );
X }
X
Xstatic time_t
Xdate_file( name )
X char* name;
X {
X FILE* f;
X char line[30000];
X time_t t;
X
X f = fopen( name, "r" );
X if ( f == (FILE*) 0 )
X {
X perror( name );
X return (time_t) -1;
X }
X
X for (;;)
X {
X if ( fgets( line, sizeof(line), f ) == (char*) 0 )
X break;
X if ( line[0] == '\n' )
X break;
X if ( strncmp( line, "Date:", 5 ) == 0 )
X {
X (void) fclose( f );
X t = date_parse( &line[5] );
X if ( t == (time_t) -1 )
X (void) fprintf(
X stderr, "%s: unparsable date in %s - %s",
X argv0, name, &line[5] );
X return t;
X }
X }
X
X (void) fprintf( stderr, "%s: no Date: line found in %s\n", argv0, name );
X (void) fclose( f );
X return (time_t) -1;
X }
X
Xstatic int
Xfile_compare( f1, f2 )
X struct file* f1;
X struct file* f2;
X {
X return f1->date - f2->date;
X }
X
Xstatic char*
Xmy_malloc( size )
X unsigned size;
X {
X char* r;
X
X r = malloc( size );
X if ( r == (char*) 0 )
X out_of_mem();
X return r;
X }
X
Xstatic char*
Xmy_realloc( p, size )
X char* p;
X unsigned size;
X {
X char* r;
X
X r = realloc( p, size );
X if ( r == (char*) 0 )
X out_of_mem();
X return r;
X }
X
Xstatic void
Xout_of_mem()
X {
X (void) fprintf( stderr, "%s: out of memory\n", argv0 );
X exit( 1 );
X }
SHAR_EOF
if test 3040 -ne "`wc -c < 'date_order.c'`"
then
echo shar: error transmitting "'date_order.c'" '(should have been 3040
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'date_parse.3'" '(1789 characters)'
if test -f 'date_parse.3'
then
echo shar: will not over-write existing file "'date_parse.3'"
else
sed 's/^X//' << \SHAR_EOF > 'date_parse.3'
X.TH date_parse 3 "11 February 1995"
X.SH NAME
Xdate_parse - parse string dates into internal form
X.SH SYNOPSIS
Xtime_t date_parse( char* str )
X.SH DESCRIPTION
X.PP
XParses a date string into standard Unix internal time form (seconds
Xsince epoch).
XThe date should be in one of the following formats:
X.nf
X N mth YYYY HH:MM:SS ampm zone
X HH:MM:SS ampm zone N mth YYYY
X wdy, N mth YYYY HH:MM:SS ampm zone
X wdy mth N HH:MM:SS ampm zone YYYY
X N mth YYYY
X HH:MM:SS ampm
X.fi
XNo-zone, no-seconds, and no-am/pm versions of each are also allowed.
XAny missing parts default to the current date/time.
XNote that dd/mm/yy and mm/dd/yy are not supported - those formats are dumb.
X.SH SPEED
X.PP
XThe implementation is just a bunch of sscanf's - small and portable, but slow.
XStill, it's not that bad.
XOn a SPARCstation 2 parsing ~70000 random dates, the average time
Xwas 0.94 msec/date.
XThis compares surprising well with the lex-based date parser from
Xthe MH package, which took 0.34 msec/date in the same test.
XThe yacc-based parser used in many netnews packages is about halfway
Xbetween the two.
X.PP
XIn any application which has to open a file for each date - and both
XMH and netnews are such applications - the difference in date parsing
Xspeed will not be perceptible to the user.
X.SH "SEE ALSO"
Xdate_sort(1), date_order(1), deltime(1), xmit_time(1)
X.SH AUTHOR
XCopyright (C) 1995 by Jef Poskanzer.
X.\" Permission to use, copy, modify, and distribute this software and its
X.\" documentation for any purpose and without fee is hereby granted, provided
X.\" that the above copyright notice appear in all copies and that both that
X.\" copyright notice and this permission notice appear in supporting
X.\" documentation. This software is provided "as is" without express or
X.\" implied warranty.
SHAR_EOF
if test 1789 -ne "`wc -c < 'date_parse.3'`"
then
echo shar: error transmitting "'date_parse.3'" '(should have been 1789
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'date_parse.c'" '(19522 characters)'
if test -f 'date_parse.c'
then
echo shar: will not over-write existing file "'date_parse.c'"
else
sed 's/^X//' << \SHAR_EOF > 'date_parse.c'
X/* date_parse - parse string dates into internal form
X**
X** Copyright (C) 1995 by Jef Poskanzer <jef(a)netcom.com>.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation. This software is provided "as is" without express or
X** implied warranty.
X*/
X
X/* For a while now I've been somewhat unhappy with the various
X** date-parsing routines available - yacc-based, lex-based, ad-hoc. Large
X** code size and not very portable are the main complaints. So I wrote a
X** new one that just does a bunch of sscanf's until one matches. Slow,
X** but small and portable. To figure out what formats to support I did a
X** survey of Date: lines in a bunch of Usenet articles. The following
X** two formats accounted for more than 99% of all articles:
X** N mth YYYY HH:MM:SS ampm zone
X** wdy, N mth YYYY HH:MM:SS ampm zone
X** I added Unix ctime() format and a few others:
X** wdy mth N HH:MM:SS ampm zone YYYY
X** HH:MM:SS ampm zone N mth YYYY
X** N mth YYYY
X** HH:MM:SS ampm
X** No-zone, no-seconds, and no-am/pm versions of each are also supported.
X** Note that dd/mm/yy and mm/dd/yy are NOT supported - those formats are
X** dumb.
X*/
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <string.h>
X#include <ctype.h>
X#include <time.h>
X
X#ifdef SYSV
Xextern long timezone;
X#define bzero(p, n) memset(p, 0, n)
X#endif /* SYSV */
X
X#undef DEBUG
X
X#ifdef DEBUG
X#define DP(str) (void) fprintf( stderr, "%s\n", str )
X#else
X#define DP(str) (0)
X#endif
X
Xstruct strint {
X char* s;
X int i;
X };
X
Xstatic void
Xpound_case( str )
X char* str;
X {
X for ( ; *str != '\0'; ++str )
X {
X if ( isupper( *str ) )
X *str = tolower( *str );
X }
X }
X
Xstatic int
Xstrint_compare( v1, v2 )
X char* v1;
X char* v2;
X {
X return strcmp( ((struct strint*) v1)->s, ((struct strint*) v2)->s );
X }
X
Xstatic int
Xstrint_search( str, tab, n, iP )
X char* str;
X struct strint* tab;
X int n;
X int* iP;
X {
X int i, h, l, r;
X
X l = 0;
X h = n - 1;
X for (;;)
X {
X i = ( h + l ) / 2;
X r = strcmp( str, tab[i].s );
X if ( r < 0 )
X h = i - 1;
X else if ( r > 0 )
X l = i + 1;
X else
X {
X *iP = tab[i].i;
X return 1;
X }
X if ( h < l )
X return 0;
X }
X }
X
X#define AMPM_NONE 0
X#define AMPM_AM 1
X#define AMPM_PM 2
Xstatic int
Xampm_fix( hour, ampm )
X int hour, ampm;
X {
X switch ( ampm )
X {
X case AMPM_NONE:
X break;
X case AMPM_AM:
X if ( hour == 12 )
X hour = 0;
X break;
X case AMPM_PM:
X if ( hour != 12 )
X hour += 12;
X break;
X }
X return hour;
X }
X
Xstatic int
Xscan_ampm( str_ampm, ampmP )
X char* str_ampm;
X int* ampmP;
X {
X static struct strint ampm_tab[] = {
X { "am", AMPM_AM }, { "pm", AMPM_PM },
X };
X static int sorted = 0;
X
X if ( ! sorted )
X {
X (void) qsort(
X ampm_tab, sizeof(ampm_tab)/sizeof(struct strint),
X sizeof(struct strint), strint_compare );
X sorted = 1;
X }
X pound_case( str_ampm );
X return strint_search(
X str_ampm, ampm_tab, sizeof(ampm_tab)/sizeof(struct strint), ampmP );
X }
X
Xstatic int
Xscan_wday( str_wday, tm_wdayP )
X char* str_wday;
X int* tm_wdayP;
X {
X static struct strint wday_tab[] = {
X { "sun", 0 }, { "sunday", 0 },
X { "mon", 1 }, { "monday", 1 },
X { "tue", 2 }, { "tuesday", 2 },
X { "wed", 3 }, { "wednesday", 3 },
X { "thu", 4 }, { "thursday", 4 },
X { "fri", 5 }, { "friday", 5 },
X { "sat", 6 }, { "saturday", 6 },
X };
X static int sorted = 0;
X
X if ( ! sorted )
X {
X (void) qsort(
X wday_tab, sizeof(wday_tab)/sizeof(struct strint),
X sizeof(struct strint), strint_compare );
X sorted = 1;
X }
X pound_case( str_wday );
X return strint_search(
X str_wday, wday_tab, sizeof(wday_tab)/sizeof(struct strint), tm_wdayP );
X }
X
Xstatic int
Xscan_mon( str_mon, tm_monP )
X char* str_mon;
X int* tm_monP;
X {
X static struct strint mon_tab[] = {
X { "jan", 0 }, { "january", 0 },
X { "feb", 1 }, { "february", 1 },
X { "mar", 2 }, { "march", 2 },
X { "apr", 3 }, { "april", 3 },
X { "may", 4 },
X { "jun", 5 }, { "june", 5 },
X { "jul", 6 }, { "july", 6 },
X { "aug", 7 }, { "august", 7 },
X { "sep", 8 }, { "september", 8 },
X { "oct", 9 }, { "october", 9 },
X { "nov", 10 }, { "november", 10 },
X { "dec", 11 }, { "december", 11 },
X };
X static int sorted = 0;
X
X if ( ! sorted )
X {
X (void) qsort(
X mon_tab, sizeof(mon_tab)/sizeof(struct strint),
X sizeof(struct strint), strint_compare );
X sorted = 1;
X }
X pound_case( str_mon );
X return strint_search(
X str_mon, mon_tab, sizeof(mon_tab)/sizeof(struct strint), tm_monP );
X }
X
Xstatic int
Xscan_gmtoff( str_gmtoff, gmtoffP )
X char* str_gmtoff;
X int* gmtoffP;
X {
X static struct strint gmtoff_tab[] = {
X { "gmt", 0 }, { "utc", 0 }, { "ut", 0 },
X { "0000", 0 }, { "+0000", 0 }, { "-0000", 0 },
X { "0100", 3600 }, { "+0100", 3600 }, { "-0100", -3600 },
X { "0200", 7200 }, { "+0200", 7200 }, { "-0200", -7200 },
X { "0300", 10800 }, { "+0300", 10800 }, { "-0300", -10800 },
X { "0400", 14400 }, { "+0400", 14400 }, { "-0400", -14400 },
X { "0500", 18000 }, { "+0500", 18000 }, { "-0500", -18000 },
X { "0600", 21600 }, { "+0600", 21600 }, { "-0600", -21600 },
X { "0700", 25200 }, { "+0700", 25200 }, { "-0700", -25200 },
X { "0800", 28800 }, { "+0800", 28800 }, { "-0800", -28800 },
X { "0900", 32400 }, { "+0900", 32400 }, { "-0900", -32400 },
X { "1000", 36000 }, { "+1000", 36000 }, { "-1000", -36000 },
X { "1100", 39600 }, { "+1100", 39600 }, { "-1100", -39600 },
X { "1200", 43200 }, { "+1200", 43200 }, { "-1200", -43200 },
X { "jst", 7200 }, { "jdt", 10800 },
X { "bst", -3600 },
X { "nst", -12600 },
X { "ast", -14400 }, { "edt", -10800 },
X { "est", -18000 }, { "edt", -14400 },
X { "cst", -21600 }, { "cdt", -18000 },
X { "mst", -25200 }, { "mdt", -21600 },
X { "pst", -28800 }, { "pdt", -25200 },
X { "yst", -32400 }, { "ydt", -28800 },
X { "hst", -36000 }, { "hdt", -32400 },
X { "a", -3600 }, { "b", -7200 }, { "c", -10800 }, { "d", -14400 },
X { "e", -18000 }, { "f", -21600 }, { "g", -25200 }, { "h", -28800 },
X { "i", -32400 }, { "k", -36000 }, { "l", -39600 }, { "m", -43200 },
X { "n", -3600 }, { "o", -7200 }, { "p", -10800 }, { "q", -14400 },
X { "r", -18000 }, { "s", -21600 }, { "t", -25200 }, { "u", -28800 },
X { "v", -32400 }, { "w", -36000 }, { "x", -39600 }, { "y", -43200 },
X };
X static int sorted = 0;
X
X if ( ! sorted )
X {
X (void) qsort(
X gmtoff_tab, sizeof(gmtoff_tab)/sizeof(struct strint),
X sizeof(struct strint), strint_compare );
X sorted = 1;
X }
X pound_case( str_gmtoff );
X return strint_search(
X str_gmtoff, gmtoff_tab, sizeof(gmtoff_tab)/sizeof(struct strint),
X gmtoffP );
X }
X
Xstatic int
Xis_leap( year )
X int year;
X {
X return year % 400? ( year % 100 ? ( year % 4 ? 0 : 1 ) : 0 ) : 1;
X }
X
X/* Basically the same as mktime(). */
Xstatic time_t
Xtm_to_time( tmP )
X struct tm* tmP;
X {
X time_t t;
X static int monthtab[12] = {
X 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
X
X /* Years since epoch, converted to days. */
X t = ( tmP->tm_year - 70 ) * 365;
X /* Leap days for previous years. */
X t += ( tmP->tm_year - 68 ) / 4;
X /* Days for the beginning of this month. */
X t += monthtab[tmP->tm_mon];
X /* Leap day for this year. */
X if ( tmP->tm_mon >= 2 && is_leap( tmP->tm_year ) )
X ++t;
X /* Days since the beginning of this month. */
X t += tmP->tm_mday - 1; /* 1-based field */
X /* Hours, minutes, and seconds. */
X t = t * 24 + tmP->tm_hour;
X t = t * 60 + tmP->tm_min;
X t = t * 60 + tmP->tm_sec;
X
X return t;
X }
X
Xtime_t
Xdate_parse( str )
X char* str;
X {
X time_t now;
X struct tm* now_tmP;
X struct tm tm;
X char* cp;
X char str_mon[500], str_wday[500], str_gmtoff[500], str_ampm[500];
X int tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year, tm_wday, gmtoff;
X int ampm, got_zone;
X time_t t;
X
X /* Initialize tm with relevant parts of current local time. */
X now = time( (time_t*) 0 );
X now_tmP = localtime( &now );
X
X bzero( (char*) &tm, sizeof(struct tm) );
X tm.tm_sec = now_tmP->tm_sec;
X tm.tm_min = now_tmP->tm_min;
X tm.tm_hour = now_tmP->tm_hour;
X tm.tm_mday = now_tmP->tm_mday;
X tm.tm_mon = now_tmP->tm_mon;
X tm.tm_year = now_tmP->tm_year;
X ampm = AMPM_NONE;
X got_zone = 0;
X
X /* Find local zone offset. This is the only real area of
X ** non-portability, and it's only used for local times that don't
X ** specify a zone - those don't occur in email and netnews.
X */
X#ifdef SYSV
X tzset();
X gmtoff = -timezone;
X#else /* SYSV */
X#ifdef BSD
X gmtoff = now_tmP->tm_gmtoff;
X#else /* BSD */
X /* You have to fill this in yourself. */
X gmtoff = !!!;
X#endif /* BSD */
X#endif /* SYSV */
X
X /* Skip initial whitespace ourselves - sscanf is clumsy at this. */
X for ( cp = str; *cp == ' ' || *cp == '\t'; ++cp )
X ;
X
X /* And do the sscanfs. WARNING: you can add more formats here,
X ** but be careful! You can easily screw up the parsing of existing
X ** formats when you add new ones.
X */
X
X /* N mth YYYY HH:MM:SS ampm zone */
X if ( ( ( sscanf( cp, "%d %[a-zA-Z] %d %d:%d:%d %[apmAPM] %[^: ]",
X &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min, &tm_sec,
X str_ampm, str_gmtoff ) == 8 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%d %[a-zA-Z] %d %d:%d:%d %[^: ]",
X &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min, &tm_sec,
X str_gmtoff ) == 7 ) &&
X scan_mon( str_mon, &tm_mon ) &&
X scan_gmtoff( str_gmtoff, &gmtoff ) )
X {
X DP( "N mth YYYY HH:MM:SS ampm zone" );
X tm.tm_mday = tm_mday;
X tm.tm_mon = tm_mon;
X tm.tm_year = tm_year;
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = tm_sec;
X got_zone = 1;
X }
X /* N mth YYYY HH:MM ampm zone */
X else if ( ( ( sscanf( cp, "%d %[a-zA-Z] %d %d:%d %[apmAPM] %[^: ]",
X &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min, str_ampm,
X str_gmtoff ) == 7 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%d %[a-zA-Z] %d %d:%d %[^: ]",
X &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
X str_gmtoff ) == 6 ) &&
X scan_mon( str_mon, &tm_mon ) &&
X scan_gmtoff( str_gmtoff, &gmtoff ) )
X {
X DP( "N mth YYYY HH:MM ampm zone" );
X tm.tm_mday = tm_mday;
X tm.tm_mon = tm_mon;
X tm.tm_year = tm_year;
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = 0;
X got_zone = 1;
X }
X /* N mth YYYY HH:MM:SS ampm */
X else if ( ( ( sscanf( cp, "%d %[a-zA-Z] %d %d:%d:%d %[apmAPM]",
X &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min, &tm_sec,
X str_ampm ) == 7 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%d %[a-zA-Z] %d %d:%d:%d",
X &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
X &tm_sec ) == 6 ) &&
X scan_mon( str_mon, &tm_mon ) )
X {
X DP( "N mth YYYY HH:MM:SS ampm" );
X tm.tm_mday = tm_mday;
X tm.tm_mon = tm_mon;
X tm.tm_year = tm_year;
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = tm_sec;
X }
X /* N mth YYYY HH:MM ampm */
X else if ( ( ( sscanf( cp, "%d %[a-zA-Z] %d %d:%d %[apmAPM]",
X &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
X str_ampm ) == 6 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%d %[a-zA-Z] %d %d:%d",
X &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min ) == 5 ) &&
X scan_mon( str_mon, &tm_mon ) )
X {
X DP( "N mth YYYY HH:MM ampm" );
X tm.tm_mday = tm_mday;
X tm.tm_mon = tm_mon;
X tm.tm_year = tm_year;
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = 0;
X }
X /* HH:MM:SS ampm zone N mth YYYY */
X else if ( ( ( sscanf( cp, "%d:%d:%d %[apmAPM] %[^: ] %d %[a-zA-Z] %d",
X &tm_hour, &tm_min, &tm_sec, str_ampm, str_gmtoff, &tm_mday,
X str_mon, &tm_year ) == 8 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%d:%d:%d %[^: ] %d %[a-zA-Z] %d",
X &tm_hour, &tm_min, &tm_sec, str_gmtoff, &tm_mday, str_mon,
X &tm_year ) == 7 ) &&
X scan_gmtoff( str_gmtoff, &gmtoff ) &&
X scan_mon( str_mon, &tm_mon ) )
X {
X DP( "HH:MM:SS ampm zone N mth YYYY" );
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = tm_sec;
X tm.tm_mday = tm_mday;
X tm.tm_mon = tm_mon;
X tm.tm_year = tm_year;
X }
X /* HH:MM ampm zone N mth YYYY */
X else if ( ( ( sscanf( cp, "%d:%d %[apmAPM] %[^: ] %d %[a-zA-Z] %d",
X &tm_hour, &tm_min, str_ampm, str_gmtoff, &tm_mday, str_mon,
X &tm_year ) == 7 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%d:%d %[^: ] %d %[a-zA-Z] %d",
X &tm_hour, &tm_min, str_gmtoff, &tm_mday, str_mon,
X &tm_year ) == 6 ) &&
X scan_gmtoff( str_gmtoff, &gmtoff ) &&
X scan_mon( str_mon, &tm_mon ) )
X {
X DP( "HH:MM ampm N mth YYYY" );
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = 0;
X tm.tm_mday = tm_mday;
X tm.tm_mon = tm_mon;
X tm.tm_year = tm_year;
X }
X /* HH:MM:SS ampm N mth YYYY */
X else if ( ( ( sscanf( cp, "%d:%d:%d %[apmAPM] %d %[a-zA-Z] %d",
X &tm_hour, &tm_min, &tm_sec, str_ampm, &tm_mday, str_mon,
X &tm_year ) == 7 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%d:%d:%d %d %[a-zA-Z] %d",
X &tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon,
X &tm_year ) == 6 ) &&
X scan_mon( str_mon, &tm_mon ) )
X {
X DP( "HH:MM:SS ampm N mth YYYY" );
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = tm_sec;
X tm.tm_mday = tm_mday;
X tm.tm_mon = tm_mon;
X tm.tm_year = tm_year;
X }
X /* HH:MM ampm N mth YYYY */
X else if ( ( ( sscanf( cp, "%d:%d %[apmAPM] %d %[a-zA-Z] %d",
X &tm_hour, &tm_min, str_ampm, &tm_mday, str_mon,
X &tm_year ) == 6 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%d:%d %d %[a-zA-Z] %d",
X &tm_hour, &tm_min, &tm_mday, str_mon, &tm_year ) == 5 ) &&
X scan_mon( str_mon, &tm_mon ) )
X {
X DP( "HH:MM ampm N mth YYYY" );
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = 0;
X tm.tm_mday = tm_mday;
X tm.tm_mon = tm_mon;
X tm.tm_year = tm_year;
X }
X /* wdy, N mth YYYY HH:MM:SS ampm zone */
X else if ( ( ( sscanf( cp, "%[a-zA-Z], %d %[a-zA-Z] %d %d:%d:%d %[apmAPM] %[^:
]",
X str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
X &tm_sec, str_ampm, str_gmtoff ) == 9 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%[a-zA-Z], %d %[a-zA-Z] %d %d:%d:%d %[^: ]",
X str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
X &tm_sec, str_gmtoff ) == 8 ) &&
X scan_wday( str_wday, &tm_wday ) &&
X scan_mon( str_mon, &tm_mon ) &&
X scan_gmtoff( str_gmtoff, &gmtoff ) )
X {
X DP( "wdy, N mth YYYY HH:MM:SS ampm zone" );
X tm.tm_wday = tm_wday;
X tm.tm_mday = tm_mday;
X tm.tm_mon = tm_mon;
X tm.tm_year = tm_year;
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = tm_sec;
X got_zone = 1;
X }
X /* wdy, N mth YYYY HH:MM ampm zone */
X else if ( ( ( sscanf( cp, "%[a-zA-Z], %d %[a-zA-Z] %d %d:%d %[apmAPM] %[^: ]",
X str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
X str_ampm, str_gmtoff ) == 8 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%[a-zA-Z], %d %[a-zA-Z] %d %d:%d %[^: ]",
X str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
X str_gmtoff ) == 7 ) &&
X scan_wday( str_wday, &tm_wday ) &&
X scan_mon( str_mon, &tm_mon ) &&
X scan_gmtoff( str_gmtoff, &gmtoff ) )
X {
X DP( "wdy, N mth YYYY HH:MM ampm zone" );
X tm.tm_wday = tm_wday;
X tm.tm_mday = tm_mday;
X tm.tm_mon = tm_mon;
X tm.tm_year = tm_year;
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = 0;
X got_zone = 1;
X }
X /* wdy, N mth YYYY HH:MM:SS ampm */
X else if ( ( ( sscanf( cp, "%[a-zA-Z], %d %[a-zA-Z] %d %d:%d:%d %[apmAPM]",
X str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
X &tm_sec, str_ampm ) == 8 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%[a-zA-Z], %d %[a-zA-Z] %d %d:%d:%d",
X str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
X &tm_sec ) == 7 ) &&
X scan_wday( str_wday, &tm_wday ) &&
X scan_mon( str_mon, &tm_mon ) )
X {
X DP( "wdy, N mth YYYY HH:MM:SS ampm" );
X tm.tm_wday = tm_wday;
X tm.tm_mday = tm_mday;
X tm.tm_mon = tm_mon;
X tm.tm_year = tm_year;
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = tm_sec;
X }
X /* wdy, N mth YYYY HH:MM ampm */
X else if ( ( ( sscanf( cp, "%[a-zA-Z], %d %[a-zA-Z] %d %d:%d %[apmAPM]",
X str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
X str_ampm ) == 7 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%[a-zA-Z], %d %[a-zA-Z] %d %d:%d",
X str_wday, &tm_mday, str_mon, &tm_year, &tm_hour,
X &tm_min ) == 6 ) &&
X scan_wday( str_wday, &tm_wday ) &&
X scan_mon( str_mon, &tm_mon ) )
X {
X DP( "wdy, N mth YYYY HH:MM ampm" );
X tm.tm_wday = tm_wday;
X tm.tm_mday = tm_mday;
X tm.tm_mon = tm_mon;
X tm.tm_year = tm_year;
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = 0;
X }
X /* wdy mth N HH:MM:SS ampm zone YYYY */
X else if ( ( ( sscanf( cp, "%[a-zA-Z] %[a-zA-Z] %d %d:%d:%d %[apmAPM] %[^: ]
%d",
X str_wday, str_mon, &tm_mday, &tm_hour, &tm_min, &tm_sec,
X str_ampm, str_gmtoff, &tm_year ) == 9 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%[a-zA-Z] %[a-zA-Z] %d %d:%d:%d %[^: ] %d",
X str_wday, str_mon, &tm_mday, &tm_hour, &tm_min, &tm_sec,
X str_gmtoff, &tm_year ) == 8 ) &&
X scan_wday( str_wday, &tm_wday ) &&
X scan_mon( str_mon, &tm_mon ) &&
X scan_gmtoff( str_gmtoff, &gmtoff ) )
X {
X DP( "wdy mth N HH:MM:SS ampm zone YYYY" );
X tm.tm_wday = tm_wday;
X tm.tm_mon = tm_mon;
X tm.tm_mday = tm_mday;
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = tm_sec;
X got_zone = 1;
X tm.tm_year = tm_year;
X }
X /* wdy mth N HH:MM ampm zone YYYY */
X else if ( ( ( sscanf( cp, "%[a-zA-Z] %[a-zA-Z] %d %d:%d %[apmAPM] %[^: ] %d",
X str_wday, str_mon, &tm_mday, &tm_hour, &tm_min,
X str_ampm, str_gmtoff, &tm_year ) == 8 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%[a-zA-Z] %[a-zA-Z] %d %d:%d %[^: ] %d",
X str_wday, str_mon, &tm_mday, &tm_hour, &tm_min,
X str_gmtoff, &tm_year ) == 7 ) &&
X scan_wday( str_wday, &tm_wday ) &&
X scan_mon( str_mon, &tm_mon ) &&
X scan_gmtoff( str_gmtoff, &gmtoff ) )
X {
X DP( "wdy mth N HH:MM ampm zone YYYY" );
X tm.tm_wday = tm_wday;
X tm.tm_mon = tm_mon;
X tm.tm_mday = tm_mday;
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = 0;
X got_zone = 1;
X tm.tm_year = tm_year;
X }
X /* N mth YYYY */
X else if ( sscanf( cp, "%d %[a-zA-Z] %d",
X &tm_mday, str_mon, &tm_year ) == 3 &&
X scan_mon( str_mon, &tm_mon ) )
X {
X DP( "N mth YYYY" );
X tm.tm_mday = tm_mday;
X tm.tm_mon = tm_mon;
X tm.tm_year = tm_year;
X tm.tm_hour = 0;
X tm.tm_min = 0;
X tm.tm_sec = 0;
X }
X /* HH:MM:SS ampm */
X else if ( ( sscanf( cp, "%d:%d:%d %[apmAPM]",
X &tm_hour, &tm_min, &tm_sec, str_ampm ) == 4 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%d:%d:%d", &tm_hour, &tm_min, &tm_sec ) == 3 )
X {
X DP( "HH:MM:SS ampm" );
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = tm_sec;
X }
X /* HH:MM ampm */
X else if ( ( sscanf( cp, "%d:%d %[apmAPM]", &tm_hour, &tm_min,
X str_ampm ) == 3 &&
X scan_ampm( str_ampm, &m ) ) ||
X sscanf( cp, "%d:%d", &tm_hour, &tm_min ) == 2 )
X {
X DP( "HH:MM" );
X tm.tm_hour = ampm_fix( tm_hour, ampm );
X tm.tm_min = tm_min;
X tm.tm_sec = 0;
X }
X else
X return (time_t) -1;
X
X if ( tm.tm_year > 1900 )
X tm.tm_year -= 1900;
X else if ( tm.tm_year < 70 )
X tm.tm_year += 100;
X
X t = tm_to_time( &tm );
X t -= gmtoff;
X if ( tm.tm_isdst && ! got_zone )
X t -= 60*60;
X
X return t;
X }
SHAR_EOF
if test 19522 -ne "`wc -c < 'date_parse.c'`"
then
echo shar: error transmitting "'date_parse.c'" '(should have been 19522
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'date_sort.1'" '(784 characters)'
if test -f 'date_sort.1'
then
echo shar: will not over-write existing file "'date_sort.1'"
else
sed 's/^X//' << \SHAR_EOF > 'date_sort.1'
X.TH date_sort 1 "11 February 1995"
X.SH NAME
Xdate_sort - sort input by date
X.SH SYNOPSIS
X.B date_sort
X.RI [ file
X.IR ... ]
X.SH DESCRIPTION
X.PP
XReads in lines from the input files or stdin.
XThe lines should consist of or begin with dates.
XSorts the lines and writes them out.
X.SH "SEE ALSO"
Xdate_order(1), deltime(1), xmit_time(1), date_parse(3)
X.SH AUTHOR
XCopyright (C) 1995 by Jef Poskanzer.
X.\" Permission to use, copy, modify, and distribute this software and its
X.\" documentation for any purpose and without fee is hereby granted, provided
X.\" that the above copyright notice appear in all copies and that both that
X.\" copyright notice and this permission notice appear in supporting
X.\" documentation. This software is provided "as is" without express or
X.\" implied warranty.
SHAR_EOF
if test 784 -ne "`wc -c < 'date_sort.1'`"
then
echo shar: error transmitting "'date_sort.1'" '(should have been 784
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'date_sort.c'" '(3085 characters)'
if test -f 'date_sort.c'
then
echo shar: will not over-write existing file "'date_sort.c'"
else
sed 's/^X//' << \SHAR_EOF > 'date_sort.c'
X/* date_sort - sort input by date
X**
X** Copyright (C) 1995 by Jef Poskanzer <jef(a)netcom.com>.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation. This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include <string.h>
X#include <malloc.h>
X#include <time.h>
X
Xextern time_t date_parse();
X
Xstatic void usage();
Xstatic void read_file();
Xstatic int line_compare();
Xstatic char* my_malloc();
Xstatic char* my_realloc();
Xstatic void out_of_mem();
X
Xstatic char* argv0;
X
Xstruct line
X {
X char* text;
X time_t date;
X };
X
Xstatic int maxlines, nlines;
Xstatic struct line* lines;
X
Xvoid
Xmain( argc, argv )
X int argc;
X char* argv[];
X {
X int argn;
X FILE* f;
X int i;
X
X argv0 = argv[0];
X argn = 1;
X if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
X usage();
X
X maxlines = 500; /* arbitrary initial value */
X lines = (struct line*) my_malloc( maxlines * sizeof(struct line) );
X nlines = 0;
X
X if ( argn == argc )
X read_file( stdin );
X else
X while ( argn < argc )
X {
X if ( strcmp( argv[argn], "-" ) == 0 )
X read_file( stdin );
X else
X {
X f = fopen( argv[argn], "r" );
X if ( f == (FILE*) 0 )
X {
X perror( argv[argn] );
X exit( 1 );
X }
X read_file( f );
X (void) fclose( f );
X }
X ++argn;
X }
X
X qsort( lines, nlines, sizeof(struct line), line_compare );
X
X for ( i = 0; i < nlines; ++i )
X fputs( lines[i].text, stdout );
X
X exit( 0 );
X }
X
Xstatic void
Xusage()
X {
X (void) fprintf( stderr, "usage: %s [file ...]\n", argv0 );
X exit( 1 );
X }
X
Xstatic void
Xread_file( f )
X FILE* f;
X {
X char aline[10000];
X
X /* Read until end of file. */
X while ( fgets( aline, sizeof(aline), f ) != (char*) 0 )
X {
X /* Make sure there's enough room in the lines array. */
X if ( nlines >= maxlines )
X {
X maxlines *= 2;
X lines = (struct line*) my_realloc(
X (char*) lines, maxlines * sizeof(struct line) );
X }
X lines[nlines].text = (char*) my_malloc( strlen( aline ) + 1 );
X (void) strcpy( lines[nlines].text, aline );
X lines[nlines].date = date_parse( aline );
X if ( lines[nlines].date == (time_t) -1 )
X (void) fprintf( stderr, "%s: unparsable date - %s", argv0, aline );
X ++nlines;
X }
X }
X
Xstatic int
Xline_compare( l1, l2 )
X struct line* l1;
X struct line* l2;
X {
X return l1->date - l2->date;
X }
X
Xstatic char*
Xmy_malloc( size )
X unsigned size;
X {
X char* r;
X
X r = malloc( size );
X if ( r == (char*) 0 )
X out_of_mem();
X return r;
X }
X
Xstatic char*
Xmy_realloc( p, size )
X char* p;
X unsigned size;
X {
X char* r;
X
X r = realloc( p, size );
X if ( r == (char*) 0 )
X out_of_mem();
X return r;
X }
X
Xstatic void
Xout_of_mem()
X {
X (void) fprintf( stderr, "%s: out of memory\n", argv0 );
X exit( 1 );
X }
SHAR_EOF
if test 3085 -ne "`wc -c < 'date_sort.c'`"
then
echo shar: error transmitting "'date_sort.c'" '(should have been 3085
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'deltime.1'" '(978 characters)'
if test -f 'deltime.1'
then
echo shar: will not over-write existing file "'deltime.1'"
else
sed 's/^X//' << \SHAR_EOF > 'deltime.1'
X.TH deltime 1 "11 February 1995"
X.SH NAME
Xdeltime - show difference between two dates
X.SH SYNOPSIS
X.B deltime
X.I date1
X.RI [ date2 ]
X.SH DESCRIPTION
X.PP
XComputes the elapsed time between now and a
Xspecified date/time, or between two specified date/times.
XBe careful to put the dates in quotes if they contain spaces.
XThe output format is dddd hh:mm:ss.
X.PP
XTimes earlier than 1970 cannot
Xbe handled, because that's as far back as the internal Unix time format goes.
X.SH "SEE ALSO"
Xdate_sort(1), date_order(1), xmit_time(1), date_parse(3)
X.SH AUTHOR
XCopyright (C) 1995 by Jef Poskanzer.
X.\" Permission to use, copy, modify, and distribute this software and its
X.\" documentation for any purpose and without fee is hereby granted, provided
X.\" that the above copyright notice appear in all copies and that both that
X.\" copyright notice and this permission notice appear in supporting
X.\" documentation. This software is provided "as is" without express or
X.\" implied warranty.
SHAR_EOF
if test 978 -ne "`wc -c < 'deltime.1'`"
then
echo shar: error transmitting "'deltime.1'" '(should have been 978
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'deltime.c'" '(1932 characters)'
if test -f 'deltime.c'
then
echo shar: will not over-write existing file "'deltime.c'"
else
sed 's/^X//' << \SHAR_EOF > 'deltime.c'
X/* deltime - show difference between two dates
X**
X** Copyright (C) 1995 by Jef Poskanzer <jef(a)netcom.com>.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation. This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include <time.h>
X
Xextern time_t date_parse();
X
Xstatic void usage();
Xstatic void unparsable();
X
Xstatic char* argv0;
X
X#define SECSPERMINUTE 60
X#define SECSPERHOUR (60 * SECSPERMINUTE)
X#define SECSPERDAY (24 * SECSPERHOUR)
X
Xvoid
Xmain( argc, argv )
X int argc;
X char* argv[];
X {
X time_t t1, t2;
X long delta;
X int days, hours, minutes, secs;
X
X argv0 = argv[0];
X
X if ( argc == 2 )
X {
X t1 = date_parse( argv[1] );
X if ( t1 == (time_t) -1 )
X unparsable( argv[1] );
X t2 = time( (time_t*) 0 );
X }
X else if ( argc == 3 )
X {
X t1 = date_parse( argv[1] );
X if ( t1 == (time_t) -1 )
X unparsable( argv[1] );
X t2 = date_parse( argv[2] );
X if ( t2 == (time_t) -1 )
X unparsable( argv[2] );
X }
X else
X usage();
X
X delta = t2 - t1;
X if ( delta < 0 )
X {
X (void) printf( "-" );
X delta = -delta;
X }
X
X days = delta / SECSPERDAY;
X delta = delta - days * SECSPERDAY;
X hours = delta / SECSPERHOUR;
X delta = delta - hours * SECSPERHOUR;
X minutes = delta / SECSPERMINUTE;
X delta = delta - minutes * SECSPERMINUTE;
X secs = delta;
X
X printf( "%d %2d:%02d:%02d\n", days, hours, minutes, secs );
X
X exit( 0 );
X }
X
Xstatic void
Xusage()
X {
X (void) fprintf( stderr, "usage: %s date1 [date2]\n", argv0 );
X exit( 1 );
X }
X
Xstatic void
Xunparsable( str )
X char* str;
X {
X (void) fprintf( stderr, "%s: unparsable date - %s\n", argv0, str );
X exit( 1 );
X }
SHAR_EOF
if test 1932 -ne "`wc -c < 'deltime.c'`"
then
echo shar: error transmitting "'deltime.c'" '(should have been 1932
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'dptest.c'" '(286 characters)'
if test -f 'dptest.c'
then
echo shar: will not over-write existing file "'dptest.c'"
else
sed 's/^X//' << \SHAR_EOF > 'dptest.c'
X#include <sys/types.h>
X#include <stdio.h>
X#include <time.h>
X
Xextern time_t date_parse();
X
Xmain( argc, argv )
X int argc;
X char* argv;
X {
X char line[5000];
X
X while ( gets( line ) != (char*) 0 )
X (void) printf( "%s - %d\n", line, date_parse( line ) );
X
X exit( 0 );
X }
SHAR_EOF
if test 286 -ne "`wc -c < 'dptest.c'`"
then
echo shar: error transmitting "'dptest.c'" '(should have been 286
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'test_input'" '(4336 characters)'
if test -f 'test_input'
then
echo shar: will not over-write existing file "'test_input'"
else
sed 's/^X//' << \SHAR_EOF > 'test_input'
X6 Feb 1995 09:00:00 AM PST
X6 Feb 1995 09:00:00 PST
X6 Feb 1995 09:00 AM PST
X6 Feb 1995 09:00 PST
X6 Feb 1995 09:00:00 AM
X6 Feb 1995 09:00:00
X6 Feb 1995 09:00 AM
X6 Feb 1995 09:00
X09:00:00 AM PST 6 Feb 1995
X09:00:00 PST 6 Feb 1995
X09:00 AM PST 6 Feb 1995
X09:00 PST 6 Feb 1995
X09:00:00 AM 6 Feb 1995
X09:00:00 6 Feb 1995
X09:00 AM 6 Feb 1995
X09:00 6 Feb 1995
XMon, 6 Feb 1995 09:00:00 AM PST
XMon, 6 Feb 1995 09:00:00 PST
XMon, 6 Feb 1995 09:00 AM PST
XMon, 6 Feb 1995 09:00 PST
XMon, 6 Feb 1995 09:00:00 AM
XMon, 6 Feb 1995 09:00:00
XMon, 6 Feb 1995 09:00 AM
XMon, 6 Feb 1995 09:00
XMon Feb 6 09:00:00 AM PST 1995
XMon Feb 6 09:00:00 PST 1995
XMon Feb 6 09:00 AM PST 1995
XMon Feb 6 09:00 PST 1995
XMon, 6 Feb 1995 09:00:00 AM PST
XMon, 6 Feb 1995 09:00:00 PM PST
XSun, 6 Feb 1995 09:00:00 PST
XSunday, 6 Feb 1995 09:00:00 PST
XMon, 6 Feb 1995 09:00:00 PST
XMonday, 6 Feb 1995 09:00:00 PST
XTue, 6 Feb 1995 09:00:00 PST
XTuesday, 6 Feb 1995 09:00:00 PST
XWed, 6 Feb 1995 09:00:00 PST
XWednesday, 6 Feb 1995 09:00:00 PST
XThu, 6 Feb 1995 09:00:00 PST
XThursday, 6 Feb 1995 09:00:00 PST
XFri, 6 Feb 1995 09:00:00 PST
XFriday, 6 Feb 1995 09:00:00 PST
XSat, 6 Feb 1995 09:00:00 PST
XSaturday, 6 Feb 1995 09:00:00 PST
XMon, 6 Jan 1995 09:00:00 PST
XMon, 6 January 1995 09:00:00 PST
XMon, 6 Feb 1995 09:00:00 PST
XMon, 6 February 1995 09:00:00 PST
XMon, 6 Mar 1995 09:00:00 PST
XMon, 6 March 1995 09:00:00 PST
XMon, 6 Apr 1995 09:00:00 PST
XMon, 6 April 1995 09:00:00 PST
XMon, 6 May 1995 09:00:00 PST
XMon, 6 Jun 1995 09:00:00 PST
XMon, 6 June 1995 09:00:00 PST
XMon, 6 Jul 1995 09:00:00 PST
XMon, 6 July 1995 09:00:00 PST
XMon, 6 Aug 1995 09:00:00 PST
XMon, 6 August 1995 09:00:00 PST
XMon, 6 Sep 1995 09:00:00 PST
XMon, 6 September 1995 09:00:00 PST
XMon, 6 Oct 1995 09:00:00 PST
XMon, 6 October 1995 09:00:00 PST
XMon, 6 Nov 1995 09:00:00 PST
XMon, 6 November 1995 09:00:00 PST
XMon, 6 Dec 1995 09:00:00 PST
XMon, 6 December 1995 09:00:00 PST
XMon, 6 Feb 1995 09:00:00 GMT
XMon, 6 Feb 1995 09:00:00 UTC
XMon, 6 Feb 1995 09:00:00 UT
XMon, 6 Feb 1995 09:00:00 0000
XMon, 6 Feb 1995 09:00:00 +0000
XMon, 6 Feb 1995 09:00:00 -0000
XMon, 6 Feb 1995 09:00:00 0100
XMon, 6 Feb 1995 09:00:00 +0100
XMon, 6 Feb 1995 09:00:00 -0100
XMon, 6 Feb 1995 09:00:00 0200
XMon, 6 Feb 1995 09:00:00 +0200
XMon, 6 Feb 1995 09:00:00 -0200
XMon, 6 Feb 1995 09:00:00 0300
XMon, 6 Feb 1995 09:00:00 +0300
XMon, 6 Feb 1995 09:00:00 -0300
XMon, 6 Feb 1995 09:00:00 0400
XMon, 6 Feb 1995 09:00:00 +0400
XMon, 6 Feb 1995 09:00:00 -0400
XMon, 6 Feb 1995 09:00:00 0500
XMon, 6 Feb 1995 09:00:00 +0500
XMon, 6 Feb 1995 09:00:00 -0500
XMon, 6 Feb 1995 09:00:00 0600
XMon, 6 Feb 1995 09:00:00 +0600
XMon, 6 Feb 1995 09:00:00 -0600
XMon, 6 Feb 1995 09:00:00 0700
XMon, 6 Feb 1995 09:00:00 +0700
XMon, 6 Feb 1995 09:00:00 -0700
XMon, 6 Feb 1995 09:00:00 0800
XMon, 6 Feb 1995 09:00:00 +0800
XMon, 6 Feb 1995 09:00:00 -0800
XMon, 6 Feb 1995 09:00:00 0900
XMon, 6 Feb 1995 09:00:00 +0900
XMon, 6 Feb 1995 09:00:00 -0900
XMon, 6 Feb 1995 09:00:00 1000
XMon, 6 Feb 1995 09:00:00 +1000
XMon, 6 Feb 1995 09:00:00 -1000
XMon, 6 Feb 1995 09:00:00 1100
XMon, 6 Feb 1995 09:00:00 +1100
XMon, 6 Feb 1995 09:00:00 -1100
XMon, 6 Feb 1995 09:00:00 1200
XMon, 6 Feb 1995 09:00:00 +1200
XMon, 6 Feb 1995 09:00:00 -1200
XMon, 6 Feb 1995 09:00:00 JST
XMon, 6 Feb 1995 09:00:00 JDT
XMon, 6 Feb 1995 09:00:00 BST
XMon, 6 Feb 1995 09:00:00 NST
XMon, 6 Feb 1995 09:00:00 AST
XMon, 6 Feb 1995 09:00:00 EDT
XMon, 6 Feb 1995 09:00:00 EST
XMon, 6 Feb 1995 09:00:00 EDT
XMon, 6 Feb 1995 09:00:00 CST
XMon, 6 Feb 1995 09:00:00 CDT
XMon, 6 Feb 1995 09:00:00 MST
XMon, 6 Feb 1995 09:00:00 MDT
XMon, 6 Feb 1995 09:00:00 PST
XMon, 6 Feb 1995 09:00:00 PDT
XMon, 6 Feb 1995 09:00:00 YST
XMon, 6 Feb 1995 09:00:00 YDT
XMon, 6 Feb 1995 09:00:00 HST
XMon, 6 Feb 1995 09:00:00 HDT
XMon, 6 Feb 1995 09:00:00 A
XMon, 6 Feb 1995 09:00:00 B
XMon, 6 Feb 1995 09:00:00 C
XMon, 6 Feb 1995 09:00:00 D
XMon, 6 Feb 1995 09:00:00 E
XMon, 6 Feb 1995 09:00:00 F
XMon, 6 Feb 1995 09:00:00 G
XMon, 6 Feb 1995 09:00:00 H
XMon, 6 Feb 1995 09:00:00 I
XMon, 6 Feb 1995 09:00:00 K
XMon, 6 Feb 1995 09:00:00 L
XMon, 6 Feb 1995 09:00:00 M
XMon, 6 Feb 1995 09:00:00 N
XMon, 6 Feb 1995 09:00:00 O
XMon, 6 Feb 1995 09:00:00 P
XMon, 6 Feb 1995 09:00:00 Q
XMon, 6 Feb 1995 09:00:00 R
XMon, 6 Feb 1995 09:00:00 S
XMon, 6 Feb 1995 09:00:00 T
XMon, 6 Feb 1995 09:00:00 U
XMon, 6 Feb 1995 09:00:00 V
XMon, 6 Feb 1995 09:00:00 W
XMon, 6 Feb 1995 09:00:00 X
XMon, 6 Feb 1995 09:00:00 Y
SHAR_EOF
if test 4336 -ne "`wc -c < 'test_input'`"
then
echo shar: error transmitting "'test_input'" '(should have been 4336
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'test_output'" '(6148 characters)'
if test -f 'test_output'
then
echo shar: will not over-write existing file "'test_output'"
else
sed 's/^X//' << \SHAR_EOF > 'test_output'
X6 Feb 1995 09:00:00 AM PST - 792090000
X6 Feb 1995 09:00:00 PST - 792090000
X6 Feb 1995 09:00 AM PST - 792090000
X6 Feb 1995 09:00 PST - 792090000
X6 Feb 1995 09:00:00 AM - 792090000
X6 Feb 1995 09:00:00 - 792090000
X6 Feb 1995 09:00 AM - 792090000
X6 Feb 1995 09:00 - 792090000
X09:00:00 AM PST 6 Feb 1995 - 792090000
X09:00:00 PST 6 Feb 1995 - 792090000
X09:00 AM PST 6 Feb 1995 - 792090000
X09:00 PST 6 Feb 1995 - 792090000
X09:00:00 AM 6 Feb 1995 - 792090000
X09:00:00 6 Feb 1995 - 792090000
X09:00 AM 6 Feb 1995 - 792090000
X09:00 6 Feb 1995 - 792090000
XMon, 6 Feb 1995 09:00:00 AM PST - 792090000
XMon, 6 Feb 1995 09:00:00 PST - 792090000
XMon, 6 Feb 1995 09:00 AM PST - 792090000
XMon, 6 Feb 1995 09:00 PST - 792090000
XMon, 6 Feb 1995 09:00:00 AM - 792090000
XMon, 6 Feb 1995 09:00:00 - 792090000
XMon, 6 Feb 1995 09:00 AM - 792090000
XMon, 6 Feb 1995 09:00 - 792090000
XMon Feb 6 09:00:00 AM PST 1995 - 792090000
XMon Feb 6 09:00:00 PST 1995 - 792090000
XMon Feb 6 09:00 AM PST 1995 - 792090000
XMon Feb 6 09:00 PST 1995 - 792090000
XMon, 6 Feb 1995 09:00:00 AM PST - 792090000
XMon, 6 Feb 1995 09:00:00 PM PST - 792133200
XSun, 6 Feb 1995 09:00:00 PST - 792090000
XSunday, 6 Feb 1995 09:00:00 PST - 792090000
XMon, 6 Feb 1995 09:00:00 PST - 792090000
XMonday, 6 Feb 1995 09:00:00 PST - 792090000
XTue, 6 Feb 1995 09:00:00 PST - 792090000
XTuesday, 6 Feb 1995 09:00:00 PST - 792090000
XWed, 6 Feb 1995 09:00:00 PST - 792090000
XWednesday, 6 Feb 1995 09:00:00 PST - 792090000
XThu, 6 Feb 1995 09:00:00 PST - 792090000
XThursday, 6 Feb 1995 09:00:00 PST - 792090000
XFri, 6 Feb 1995 09:00:00 PST - 792090000
XFriday, 6 Feb 1995 09:00:00 PST - 792090000
XSat, 6 Feb 1995 09:00:00 PST - 792090000
XSaturday, 6 Feb 1995 09:00:00 PST - 792090000
XMon, 6 Jan 1995 09:00:00 PST - 789411600
XMon, 6 January 1995 09:00:00 PST - 789411600
XMon, 6 Feb 1995 09:00:00 PST - 792090000
XMon, 6 February 1995 09:00:00 PST - 792090000
XMon, 6 Mar 1995 09:00:00 PST - 794509200
XMon, 6 March 1995 09:00:00 PST - 794509200
XMon, 6 Apr 1995 09:00:00 PST - 797187600
XMon, 6 April 1995 09:00:00 PST - 797187600
XMon, 6 May 1995 09:00:00 PST - 799779600
XMon, 6 Jun 1995 09:00:00 PST - 802458000
XMon, 6 June 1995 09:00:00 PST - 802458000
XMon, 6 Jul 1995 09:00:00 PST - 805050000
XMon, 6 July 1995 09:00:00 PST - 805050000
XMon, 6 Aug 1995 09:00:00 PST - 807728400
XMon, 6 August 1995 09:00:00 PST - 807728400
XMon, 6 Sep 1995 09:00:00 PST - 810406800
XMon, 6 September 1995 09:00:00 PST - 810406800
XMon, 6 Oct 1995 09:00:00 PST - 812998800
XMon, 6 October 1995 09:00:00 PST - 812998800
XMon, 6 Nov 1995 09:00:00 PST - 815677200
XMon, 6 November 1995 09:00:00 PST - 815677200
XMon, 6 Dec 1995 09:00:00 PST - 818269200
XMon, 6 December 1995 09:00:00 PST - 818269200
XMon, 6 Feb 1995 09:00:00 GMT - 792061200
XMon, 6 Feb 1995 09:00:00 UTC - 792061200
XMon, 6 Feb 1995 09:00:00 UT - 792061200
XMon, 6 Feb 1995 09:00:00 0000 - 792061200
XMon, 6 Feb 1995 09:00:00 +0000 - 792061200
XMon, 6 Feb 1995 09:00:00 -0000 - 792061200
XMon, 6 Feb 1995 09:00:00 0100 - 792057600
XMon, 6 Feb 1995 09:00:00 +0100 - 792057600
XMon, 6 Feb 1995 09:00:00 -0100 - 792064800
XMon, 6 Feb 1995 09:00:00 0200 - 792054000
XMon, 6 Feb 1995 09:00:00 +0200 - 792054000
XMon, 6 Feb 1995 09:00:00 -0200 - 792068400
XMon, 6 Feb 1995 09:00:00 0300 - 792050400
XMon, 6 Feb 1995 09:00:00 +0300 - 792050400
XMon, 6 Feb 1995 09:00:00 -0300 - 792072000
XMon, 6 Feb 1995 09:00:00 0400 - 792046800
XMon, 6 Feb 1995 09:00:00 +0400 - 792046800
XMon, 6 Feb 1995 09:00:00 -0400 - 792075600
XMon, 6 Feb 1995 09:00:00 0500 - 792043200
XMon, 6 Feb 1995 09:00:00 +0500 - 792043200
XMon, 6 Feb 1995 09:00:00 -0500 - 792079200
XMon, 6 Feb 1995 09:00:00 0600 - 792039600
XMon, 6 Feb 1995 09:00:00 +0600 - 792039600
XMon, 6 Feb 1995 09:00:00 -0600 - 792082800
XMon, 6 Feb 1995 09:00:00 0700 - 792036000
XMon, 6 Feb 1995 09:00:00 +0700 - 792036000
XMon, 6 Feb 1995 09:00:00 -0700 - 792086400
XMon, 6 Feb 1995 09:00:00 0800 - 792032400
XMon, 6 Feb 1995 09:00:00 +0800 - 792032400
XMon, 6 Feb 1995 09:00:00 -0800 - 792090000
XMon, 6 Feb 1995 09:00:00 0900 - 792028800
XMon, 6 Feb 1995 09:00:00 +0900 - 792028800
XMon, 6 Feb 1995 09:00:00 -0900 - 792093600
XMon, 6 Feb 1995 09:00:00 1000 - 792025200
XMon, 6 Feb 1995 09:00:00 +1000 - 792025200
XMon, 6 Feb 1995 09:00:00 -1000 - 792097200
XMon, 6 Feb 1995 09:00:00 1100 - 792021600
XMon, 6 Feb 1995 09:00:00 +1100 - 792021600
XMon, 6 Feb 1995 09:00:00 -1100 - 792100800
XMon, 6 Feb 1995 09:00:00 1200 - 792018000
XMon, 6 Feb 1995 09:00:00 +1200 - 792018000
XMon, 6 Feb 1995 09:00:00 -1200 - 792104400
XMon, 6 Feb 1995 09:00:00 JST - 792054000
XMon, 6 Feb 1995 09:00:00 JDT - 792050400
XMon, 6 Feb 1995 09:00:00 BST - 792064800
XMon, 6 Feb 1995 09:00:00 NST - 792073800
XMon, 6 Feb 1995 09:00:00 AST - 792075600
XMon, 6 Feb 1995 09:00:00 EDT - 792072000
XMon, 6 Feb 1995 09:00:00 EST - 792079200
XMon, 6 Feb 1995 09:00:00 EDT - 792072000
XMon, 6 Feb 1995 09:00:00 CST - 792082800
XMon, 6 Feb 1995 09:00:00 CDT - 792079200
XMon, 6 Feb 1995 09:00:00 MST - 792086400
XMon, 6 Feb 1995 09:00:00 MDT - 792082800
XMon, 6 Feb 1995 09:00:00 PST - 792090000
XMon, 6 Feb 1995 09:00:00 PDT - 792086400
XMon, 6 Feb 1995 09:00:00 YST - 792093600
XMon, 6 Feb 1995 09:00:00 YDT - 792090000
XMon, 6 Feb 1995 09:00:00 HST - 792097200
XMon, 6 Feb 1995 09:00:00 HDT - 792093600
XMon, 6 Feb 1995 09:00:00 A - 792064800
XMon, 6 Feb 1995 09:00:00 B - 792068400
XMon, 6 Feb 1995 09:00:00 C - 792072000
XMon, 6 Feb 1995 09:00:00 D - 792075600
XMon, 6 Feb 1995 09:00:00 E - 792079200
XMon, 6 Feb 1995 09:00:00 F - 792082800
XMon, 6 Feb 1995 09:00:00 G - 792086400
XMon, 6 Feb 1995 09:00:00 H - 792090000
XMon, 6 Feb 1995 09:00:00 I - 792093600
XMon, 6 Feb 1995 09:00:00 K - 792097200
XMon, 6 Feb 1995 09:00:00 L - 792100800
XMon, 6 Feb 1995 09:00:00 M - 792104400
XMon, 6 Feb 1995 09:00:00 N - 792064800
XMon, 6 Feb 1995 09:00:00 O - 792068400
XMon, 6 Feb 1995 09:00:00 P - 792072000
XMon, 6 Feb 1995 09:00:00 Q - 792075600
XMon, 6 Feb 1995 09:00:00 R - 792079200
XMon, 6 Feb 1995 09:00:00 S - 792082800
XMon, 6 Feb 1995 09:00:00 T - 792086400
XMon, 6 Feb 1995 09:00:00 U - 792090000
XMon, 6 Feb 1995 09:00:00 V - 792093600
XMon, 6 Feb 1995 09:00:00 W - 792097200
XMon, 6 Feb 1995 09:00:00 X - 792100800
XMon, 6 Feb 1995 09:00:00 Y - 792104400
SHAR_EOF
if test 6148 -ne "`wc -c < 'test_output'`"
then
echo shar: error transmitting "'test_output'" '(should have been 6148
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'xmit_time.1'" '(989 characters)'
if test -f 'xmit_time.1'
then
echo shar: will not over-write existing file "'xmit_time.1'"
else
sed 's/^X//' << \SHAR_EOF > 'xmit_time.1'
X.TH xmit_time 1 "11 February 1995"
X.SH NAME
Xxmit_time - figure transmission time of netnews articles
X.SH SYNOPSIS
X.B xmit_time
X.IR file ...
X.SH DESCRIPTION
X.PP
XGiven a set of netnews article filenames as arguments, looks in each file for
Xa netnews-format Date: line.
XAlso looks at the last-modified time of the file.
XThe difference between the two is how long it took that article to
Xtravel from the poster's site to your site, and that number (in seconds)
Xis written to stdout.
X.SH "SEE ALSO"
Xdate_sort(1), date_order(1), deltime(1), date_parse(3)
X.SH AUTHOR
XCopyright (C) 1995 by Jef Poskanzer.
X.\" Permission to use, copy, modify, and distribute this software and its
X.\" documentation for any purpose and without fee is hereby granted, provided
X.\" that the above copyright notice appear in all copies and that both that
X.\" copyright notice and this permission notice appear in supporting
X.\" documentation. This software is provided "as is" without express or
X.\" implied warranty.
SHAR_EOF
if test 989 -ne "`wc -c < 'xmit_time.1'`"
then
echo shar: error transmitting "'xmit_time.1'" '(should have been 989
characters)'
fi
fi # end of overwriting check
echo shar: extracting "'xmit_time.c'" '(1975 characters)'
if test -f 'xmit_time.c'
then
echo shar: will not over-write existing file "'xmit_time.c'"
else
sed 's/^X//' << \SHAR_EOF > 'xmit_time.c'
X/* xmit_time - figure out transmission time of netnews articles
X**
X** Copyright (C) 1995 by Jef Poskanzer <jef(a)netcom.com>.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation. This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include <string.h>
X#include <sys/stat.h>
X#include <time.h>
X
Xextern time_t date_parse();
X
Xstatic void usage();
Xstatic void do_file();
X
Xstatic char* argv0;
X
Xvoid
Xmain( argc, argv )
X int argc;
X char* argv[];
X {
X int argn;
X
X argv0 = argv[0];
X argn = 1;
X if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
X usage();
X
X while ( argn < argc )
X {
X do_file( argv[argn] );
X ++argn;
X }
X
X exit( 0 );
X }
X
Xstatic void
Xusage()
X {
X (void) fprintf( stderr, "usage: %s file ...\n", argv0 );
X exit( 1 );
X }
X
Xstatic void
Xdo_file( name )
X char* name;
X {
X struct stat sb;
X time_t posted, arrived;
X FILE* f;
X char line[30000];
X
X f = fopen( name, "r" );
X if ( f == (FILE*) 0 )
X {
X perror( name );
X return;
X }
X
X if ( fstat( fileno( f ), &sb ) < 0 )
X {
X perror( name );
X (void) fclose( f );
X return;
X }
X arrived = sb.st_mtime;
X
X for (;;)
X {
X if ( fgets( line, sizeof(line), f ) == (char*) 0 )
X break;
X if ( line[0] == '\n' )
X break;
X if ( strncmp( line, "Date:", 5 ) == 0 )
X {
X (void) fclose( f );
X posted = date_parse( &line[5] );
X if ( posted == (time_t) -1 )
X (void) fprintf(
X stderr, "%s: unparsable date in %s - %s",
X argv0, name, &line[5] );
X else
X (void) printf( "%d\n", arrived - posted );
X return;
X }
X }
X
X (void) fprintf( stderr, "%s: no Date: line found in %s\n", argv0, name );
X (void) fclose( f );
X }
X
X
SHAR_EOF
if test 1975 -ne "`wc -c < 'xmit_time.c'`"
then
echo shar: error transmitting "'xmit_time.c'" '(should have been 1975
characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
1
0
betatzcodeb.tar.gz is now on elsie.nci.nih.gov; the difference is a change to
tzfile.h, the need for which was spotted by Earl Chew <earl(a)hpato.aus.hp.com>.
A diff is attached.
--ado
SCCS/s.tzfile.h: 7.5 vs. 7.6
*** 7.5/tzfile.h Fri Jan 13 19:14:26 1995
--- 7.6/tzfile.h Fri Jan 13 19:14:27 1995
***************
*** 16,22 ****
#ifndef lint
#ifndef NOID
! static char tzfilehid[] = "@(#)tzfile.h 7.5";
#endif /* !defined NOID */
#endif /* !defined lint */
--- 16,22 ----
#ifndef lint
#ifndef NOID
! static char tzfilehid[] = "@(#)tzfile.h 7.6";
#endif /* !defined NOID */
#endif /* !defined lint */
***************
*** 95,101 ****
#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
#endif /* !defined NOSOLAR */
#ifdef NOSOLAR
! #define TZ_MAX_TYPES 10 /* Maximum number of local time types */
#endif /* !defined NOSOLAR */
#endif /* !defined TZ_MAX_TYPES */
--- 95,105 ----
#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
#endif /* !defined NOSOLAR */
#ifdef NOSOLAR
! /*
! ** Must be at least 14 for Europe/Riga as of Jan 12 1995,
! ** as noted by Earl Chew <earl(a)hpato.aus.hp.com>.
! */
! #define TZ_MAX_TYPES 20 /* Maximum number of local time types */
#endif /* !defined NOSOLAR */
#endif /* !defined TZ_MAX_TYPES */
1
0
Do you know of a source, commercial or otherwise, or lat/lon
boundaries of timezones? I have an application that would be
considerably improved if, given the lat/lon of a size, the
timezone and DST calculations could be made.
If it matters, I currently only need this for the US, but it
would be nice to include some world timezones as well.
Thanks for your help. Please email replies to dhagberg(a)gds.com.
-=- D. J. Hagberg
1
0
The files
betatzcode.tar.gz
and
betatzdata.tar.gz
are now available for anonymous ftp from elsie.nci.nih.gov.
The data files use new features to allow common handling of EC countries;
the code files have been delinted, along with elimination of no-longer-needed
(I hope!) support for systems and compilers without some POSIX stuff.
(Sufficient support for off-the-shelf SunOS 4.1.1 remains.)
Any and all feedback most welcome; in particular let me know if I've
overstepped or understepped on code pruning. I trust that "tzcode95a.tar.gz"
and "tzdata95a.tar.gz" can be put in place some time before the end of the
month, while "classictzcode.tar.gz" and "classictzdata.tar.gz" will remain in
place.
Many thanks to Paul Eggert for a passle of delinting and data corrections!
--ado
1
0
I seem to have some conflicting information, can anyone confirm
for me -- is Great Britain doing the GMT->BST shift on the
last Sunday in March, 1995, and the BST->GMT shift on the
last Sunday in October, 1995? I have some data that says
the second shift will happen on Oct 22, 1995, and some which
says it is Oct 29, 1995.
>From 1996 on, I take it the dates will always be last Sunday
in March and October, to match other EEC timezones.
Thanks,
--peggyd(a)sco.com
1
0
I think you (Guy) have fairly accurately covered the issue.
I agree that the POSIX rationale is confused, and wonder why they
did not seek guidance from the C standards committee since we did
thoroughly research and analyze this issue before settling on the
specification in the C standard (which intentionally contains one
or more small ambiguities to accommodate systems that cannot get
time conversion precisely right for whatever reason). The intention
is for struct tm to contain the "user-interface" time components and
for all computations to be performed using corresponding time_t data,
which in the general C standard is a magic cookie but which is
supposed to be a uniformly ticking clock value in POSIX (with the
number of ticks per second a system macro). Standard C provides a
difftime() function simply because some systems may not have as
clean an internal representation of time_t as UNIX does.
The oscillators is supposed to tick uniformly (with very tiny
tweaks to track an accepted time standard, but no "leaps" of any
sort), and time_t should be an affine function of the number of
accrued clock ticks. If POSIX has managed to require that the
internal clock jump back and forth then it has a bug that should
be fixed. "Leap seconds", like Daylight Saving Time, is an artifice
due to people having an imperfect handle on the underlying nicely
flowing physical phenomenon of time. That's the model behind the
C standard and should be the one behind POSIX if it is to be a good
specification.
1
0
The files tzcode94h.tar.gz and tzdata94h.tar.gz are now available for
anonymous ftp from the "pub" directory on elsie.nci.nih.gov (165.112.73.1).
The files:
* incorporate the changes to "zdump" and "date" to make changes to
the "TZ" environment variable permanent;
* incorporate the table changes that Paul Eggert sent in earlier this
week;
* include (and document) support for universal time specifications in
data files--but do not (yet) include use of this feature in the
data files.
Think of this as "TZ Classic"--the software has been set up not to break if
universal time shows up in its input, and the data has been left as is so as
not to break existing implementations.
What I'd like to do is get any other important functional changes rolled in to
the code by the end of the year, then keep whatever version we've arrived
at by then available on elsie. With that insurance in hand, the hope would be
that in early 1995 the Europe data could be simplified by using the universal
time support, and that (long deferred) code cleanup could be accomplished
(perhaps with some removal of support for non-POSIX C compilers). Any insights
folks have on these notions are welcome.
Note that the Europe cleanup will require some care, since there are some
places that use the "W-Eur", "M-Eur", and "E-Eur" rules but do not switch
at 1:00 universal time. To get a sense of the issues involved, save the
existing "europe" file as "europe-old", copy it to "europe-new", edit it
to use the universal time support, unshar the attached file, then use the
command
sh regress europe-old europe-new
and ponder the results.
Also attached are the changes to "zic.c" (and "zic.8") for universal time
support.
--ado
#! /bin/sh
: To unbundle, sh this file
echo file 'regress' >&2
cat >'regress' <<'End of regress'
#! /bin/sh
T1=,reg-$$a
T2=,reg-$$b
trap 'rm -f -r $T1 $T2; exit' 0 1 2 3 15
case $# in
2) ;;
*) echo "$O: usage is $O filename filename" 1>&2
exit 1 ;;
esac
zic -d $T1 $1
zic -d $T2 $2
diff -r $T1 $T2
End of regress
exit
===============================================================================
SCCS/s.zic.c: 7.27 vs. 7.28
*** 7.27/zic.c Sat Dec 10 13:09:20 1994
--- 7.28/zic.c Sat Dec 10 13:09:21 1994
***************
*** 1,6 ****
#ifndef lint
#ifndef NOID
! static char elsieid[] = "@(#)zic.c 7.27";
#endif /* !defined NOID */
#endif /* !defined lint */
--- 1,6 ----
#ifndef lint
#ifndef NOID
! static char elsieid[] = "@(#)zic.c 7.28";
#endif /* !defined NOID */
#endif /* !defined lint */
***************
*** 25,30 ****
--- 25,32 ----
long r_tod; /* time from midnight */
int r_todisstd; /* above is standard time if TRUE */
/* or wall clock time if FALSE */
+ int r_todisuniv; /* above is universal time if TRUE */
+ /* or local time if FALSE */
long r_stdoff; /* offset from standard time */
const char * r_abbrvar; /* variable part of abbreviation */
***************
*** 1113,1129 ****
}
rp->r_month = lp->l_value;
rp->r_todisstd = FALSE;
dp = ecpyalloc(timep);
if (*dp != '\0') {
ep = dp + strlen(dp) - 1;
switch (lowerit(*ep)) {
! case 's':
rp->r_todisstd = TRUE;
*ep = '\0';
break;
! case 'w':
rp->r_todisstd = FALSE;
*ep = '\0';
break;
}
}
--- 1115,1140 ----
}
rp->r_month = lp->l_value;
rp->r_todisstd = FALSE;
+ rp->r_todisuniv = FALSE;
dp = ecpyalloc(timep);
if (*dp != '\0') {
ep = dp + strlen(dp) - 1;
switch (lowerit(*ep)) {
! case 's': /* Standard */
rp->r_todisstd = TRUE;
+ rp->r_todisuniv = FALSE;
*ep = '\0';
break;
! case 'w': /* Wall */
rp->r_todisstd = FALSE;
+ rp->r_todisuniv = FALSE;
*ep = '\0';
+ case 'g': /* Greenwich */
+ case 'u': /* Universal */
+ case 'z': /* Zulu */
+ rp->r_todisstd = TRUE;
+ rp->r_todisuniv = TRUE;
+ *ep = '\0';
break;
}
}
***************
*** 1421,1428 ****
** assuming the current gmtoff and
** stdoff values.
*/
! untiltime = tadd(zp->z_untiltime,
! -gmtoff);
if (!zp->z_untilrule.r_todisstd)
untiltime = tadd(untiltime,
-stdoff);
--- 1432,1441 ----
** assuming the current gmtoff and
** stdoff values.
*/
! untiltime = zp->z_untiltime;
! if (!zp->z_untilrule.r_todisuniv)
! untiltime = tadd(untiltime,
! -gmtoff);
if (!zp->z_untilrule.r_todisstd)
untiltime = tadd(untiltime,
-stdoff);
***************
*** 1441,1447 ****
continue;
eats(zp->z_filename, zp->z_linenum,
rp->r_filename, rp->r_linenum);
! offset = gmtoff;
if (!rp->r_todisstd)
offset = oadd(offset, stdoff);
jtime = rp->r_temp;
--- 1454,1460 ----
continue;
eats(zp->z_filename, zp->z_linenum,
rp->r_filename, rp->r_linenum);
! offset = rp->r_todisuniv ? 0 : gmtoff;
if (!rp->r_todisstd)
offset = oadd(offset, stdoff);
jtime = rp->r_temp;
===============================================================================
SCCS/s.zic.8: 7.8 vs. 7.10
*** 7.8/zic.8 Sat Dec 10 13:09:37 1994
--- 7.10/zic.8 Sat Dec 10 13:09:38 1994
***************
*** 209,222 ****
.B w
if the given time is local
.q "wall clock"
! time or
.B s
if the given time is local
.q standard
! time; in the absence of
! .B w
or
! .BR s ,
wall clock time is assumed.
.TP
.B SAVE
--- 209,226 ----
.B w
if the given time is local
.q "wall clock"
! time,
.B s
if the given time is local
.q standard
! time, or
! .B u
! (or
! .B g
or
! .BR z )
! if the given time is universal time;
! in the absence of an indicator,
wall clock time is assumed.
.TP
.B SAVE
***************
*** 399,402 ****
/usr/local/etc/zoneinfo standard directory used for created files
.SH "SEE ALSO"
newctime(3), tzfile(5), zdump(8)
! .\" @(#)zic.8 7.8
--- 403,406 ----
/usr/local/etc/zoneinfo standard directory used for created files
.SH "SEE ALSO"
newctime(3), tzfile(5), zdump(8)
! .\" @(#)zic.8 7.10
1
0
Doug Gwyn <gwyn(a)arl.mil> writes:
> UNIX "system time" is *unaffected* by Daylight
> Saving Time; it always counts clock ticks since a fixed epoch, which
> progresses unformly regardless of legislative actions. The mapping to/from
> human-being time is performed by library functions that can be instructed
> as to the exact rules to be applied
Do you believe this concept should be extended to leap seconds?
The `ado' time package proves such an extension is feasible. (The only
slight problem I've seen in practice is with programs that assume every
minute has 60 seconds.)
However, POSIX seems to legislate the possibility away, and the NTP
implementors seem to favour a complex system that jumps the clock.
Bradley
2
1
> From: Paul Eggert <eggert(a)twinsun.com>
>
> For the 1996 EC / EU daylight savings changes, we need at least four
> rulesets, one each for Western, Middle, and Eastern Europe (since the
> change is UTC, not local time), and one for GB-Eire (since they will
> continue to use `GMT' and `BST' instead of `WET' and `WET DST').
Or implement my suggestion for a means of specifying a change at a UTC time.
The GB-Eire point about using GMT/BST is still valid, I can't see us changing.
> Perhaps the simplest thing is to use the existing ruleset names,
> using a comment to explain that as of 1996 the [WME]-Eur and GB-Eire
> rulesets use the EC rules.
Remember that there isn't anything magic about the EC rules in this seventh
Directive. They are just the same sort of EC rules as in the first to sixth
Directives. The only thing that changed was the agreement of a common end
date. The UK/Eire end date in previous Directives was just as much an EC
rule as any other.
In particular, all EC Directives have used a changeover time of 01:00 UTC,
right back to 1981. (At least, I am pretty sure they did, I don't have
the text for the 1st--5th, but the UK changed from its traditional 02:00 GMT
to 01:00 in 1981.)
> The biggest near-term problem in this area will be countries that
> currently differ from the EC rules only in that they switch at
> midnight UTC instead of the new standard 01:00. It will be a hassle
> to find exactly when they change their rules. We found out with
> Finland only because someone sent us a bug report. Countries in this
> category currently include Albania, Bulgaria, Estonia, Greece, Latvia,
> Lithuania, Moldova, Poland, Romania, Turkey, and Ukraine. Greece is
> the only country in this list that is required to change because it's
> in the EC, but most likely the rest will follow at some point.
Greece should have changed in 1981, it joined in the year the first Directive
took effect. I have no idea whether it actually did I'm afraid.
Peter Ilieve peter(a)memex.co.uk
1
0
patches to zdump.c and date.c for Posix-compliant tzset behavior
by eggertï¼ twinsun.com Dec. 6, 1994
by eggertï¼ twinsun.com Dec. 6, 1994
Dec. 6, 1994
date.c and zdump.c currently use the trick of temporarily setting
`environ' to modify "TZ", then calling tzset(), then restoring
`environ', then calling `localtime' to get the effect of the
temporarily modified "TZ". But this trick doesn't work if `ctime',
`localtime', `mktime', and `strftime' inspect "TZ" every time they are
invoked, as required by Posix 1003.1b-1993 section 8.1.1 page 192
lines 54-56. The following patch fixes date.c and zdump.c to set
`environ' permanently; this should work regardless of whether tzset
has the Posix-required behavior or the old tz behavior. (I've already
sent a patch to fix the old tz behavior -- I can resend this to
whoever's interested.)
===================================================================
RCS file: RCS/date.c,v
retrieving revision 1994.6.1.2
retrieving revision 1994.6.1.3
diff -c -r1994.6.1.2 -r1994.6.1.3
*** date.c 1994/05/09 09:47:28 1994.6.1.2
--- date.c 1994/12/06 17:13:55 1994.6.1.3
***************
*** 299,312 ****
static void
dogmt()
{
! register char ** saveenv;
! static char TZ_GMT0[] = "TZ=GMT0";
! static char * fakeenv[] = { TZ_GMT0, NULL };
! saveenv = environ;
! environ = fakeenv;
! tzset();
! environ = saveenv;
}
#ifdef OLD_TIME
--- 299,320 ----
static void
dogmt()
{
! static char **fakeenv;
! if (!fakeenv) {
! register int i, j;
! for (i = 0; environ[i]; i++)
! continue;
! if (!(fakeenv = (char **) malloc((i + 2) * sizeof(char *)))) {
! (void) perror("Memory exhausted");
! errensure();
! (void) exit(retval);
! }
! fakeenv[0] = "TZ=GMT0";
! for (i = 0, j = 1; (fakeenv[j] = environ[i]) != 0; i++)
! j += strncmp(fakeenv[j], "TZ=", 3) != 0;
! environ = fakeenv;
! }
}
#ifdef OLD_TIME
===================================================================
RCS file: RCS/zdump.c,v
retrieving revision 1994.6.1.1
retrieving revision 1994.6.1.2
diff -c -r1994.6.1.1 -r1994.6.1.2
*** zdump.c 1994/05/05 16:24:49 1994.6.1.1
--- zdump.c 1994/12/06 17:13:55 1994.6.1.2
***************
*** 41,47 ****
/* localtime.c */
extern char * tzname[];
- extern void tzset P((void));
#ifndef MAX_STRING_LENGTH
#define MAX_STRING_LENGTH 1024
--- 41,46 ----
***************
*** 116,121 ****
--- 115,121 ----
register char * cutoff;
register int cutyear;
register long cuttime;
+ char ** fakeenv;
time_t now;
time_t t, newt;
time_t hibit;
***************
*** 154,178 ****
longest = strlen(argv[i]);
for (hibit = 1; (hibit << 1) != 0; hibit <<= 1)
continue;
for (i = optind; i < argc; ++i) {
- register char ** saveenv;
static char buf[MAX_STRING_LENGTH];
- char * fakeenv[2];
! if (strlen(argv[i]) + 4 > sizeof buf) {
! (void) fflush(stdout);
! (void) fprintf(stderr, "%s: argument too long -- %s\n",
! progname, argv[i]);
! (void) exit(EXIT_FAILURE);
! }
! (void) strcpy(buf, "TZ=");
! (void) strcat(buf, argv[i]);
! fakeenv[0] = buf;
! fakeenv[1] = NULL;
! saveenv = environ;
! environ = fakeenv;
! (void) tzset();
! environ = saveenv;
show(argv[i], now, FALSE);
if (!vflag)
continue;
--- 154,176 ----
longest = strlen(argv[i]);
for (hibit = 1; (hibit << 1) != 0; hibit <<= 1)
continue;
+
+ for (i = 0; environ[i]; i++)
+ continue;
+ if (!(fakeenv = (char **) malloc((i + 2) * sizeof(char *)))
+ || !(fakeenv[0] = malloc(longest + 4))) {
+ (void) perror(progname);
+ (void) exit(EXIT_FAILURE);
+ }
+ (void) strcpy(fakeenv[0], "TZ=");
+ for (i = 0, c = 1; (fakeenv[c] = environ[i]) != 0; i++)
+ c += strncmp(fakeenv[c], "TZ=", 3) != 0;
+ environ = fakeenv;
+
for (i = optind; i < argc; ++i) {
static char buf[MAX_STRING_LENGTH];
! (void) strcpy(fakeenv[0] + 3, argv[i]);
show(argv[i], now, FALSE);
if (!vflag)
continue;
1
0