[comp.bugs.sys5] date

tneff@bfmny0.BFM.COM (Tom Neff) (08/22/90)

In article <1990Aug22.155343.4058@pcrat.uucp> rick@pcrat.uucp (Rick Richardson) writes:
>Actually, it would be superb if the date(1) command were
>extended to allow both a time specification and a format
>specification, so that a shell script could print a
>date in the future (or past) using the format specifiers. E.G.
>
>	$ date 0101000090 +%w
>	1
>	$
 [...]

Well I don't quite have that, but I wrote the following a few months ago
for a similar purpose.  It's called 'ago' and it works exactly like
'date' except you can specify offsets into past or future.


#! /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:
#	README
#	ago.1
#	ago.c
# This archive created: Fri Jan 12 20:25:03 1990
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'README'
then
	echo shar: "will not over-write existing file 'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
X
XAGO is a System V command to display formatted date/time strings for
Xtimes in the past or future.  I needed to do this and couldn't find
Xanything out there, so voila!
X
XYou will need getopt(3C) to parse the command line.  If this isn't
Xin your standard C library, get one of the PD versions and link it in.
X
X
X
X@(#) README	$Revision: 1.1 $		$Date: 90/01/12 20:15:47 $
SHAR_EOF
fi
if test -f 'ago.1'
then
	echo shar: "will not over-write existing file 'ago.1'"
else
sed 's/^X//' << \SHAR_EOF > 'ago.1'
X'\"	@(#) $Id: ago.1,v 1.1 90/01/12 20:22:39 tneff Exp $
X.TH AGO 1
X.SH NAME
X\fBago\fR \- display date for times in the past or future
X.SH USAGE
X.B ago 
X.B [-s secs] 
X.B [-m mins] 
X.B [-h hrs] 
X.B [-d days] 
X.B [-w wks] 
X.B [+fmt]
X.SH DESCRIPTION
XThe
X.I ago
Xcommand is an extension to date(1) that displays a formatted date/time
Xstring for a moment in the past or future, specified in seconds, minutes,
Xhours, days and/or weeks relative to now.
X.I ago
Xaccepts the same format string as date(1).
X.sp
XWith no parameters specified,
Xor with only
X.I +fmt
Xspecified,
X.I ago
Xbehaves exactly like date(1).
XIf any of
X.I \-s \-m \-h \-d \-w
Xare specified,
X.I ago
X.B subtracts
Xthe argument values from the current time before display.
X(Specifying negative arguments will
X.B add
Xthe values to the current time, i.e., point into the future.)
X.sp
XFor further details on the format string, see date(1).
X.SH EXAMPLES
X.sp
X$ ago 
X.br
XFri Jan 12 17:22:05 EST 1990
X.sp
X$ ago -d20 -h3
X.br
XSat Dec 23 14:23:00 EST 1989
X.sp
X$ ago -w-3
X.br
XFri Feb  2 17:23:41 EST 1990
X.sp
X$ ago -d-1 +'Tomorrow is %A!'
X.br
XTomorrow is Saturday!
X.SH SEE ALSO
X.BR date(1), cftime(3C).
SHAR_EOF
fi
if test -f 'ago.c'
then
	echo shar: "will not over-write existing file 'ago.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ago.c'
X/*
X * ago - display date for times in the past or future
X *
X * usage:
X *	ago [-s secs] [-m mins] [-h hrs] [-d days] [-w wks] [+fmt]
X *
X * where:
X *	-s secs		Specifies how far into the past to look.
X *	-m mins		A negative argument looks into the future.
X *	-h hrs
X *	-d days
X *	-w wks
X *
X *	+fmt		is a cftime(3C) format string with a leading '+'
X *			for compatibility with date(1).  If omitted, the
X *			date(1) default of "%a %b %e %T %Z %Y" is used.
X *
X * NOTE:
X *	Uses getopt(3C) to parse the command line.
X *
X * $Log:	ago.c,v $
X * Revision 1.1  90/01/12  20:20:13  tneff
X * Initial revision
X * 
X */
X
X#ident "@(#) $Id: ago.c,v 1.1 90/01/12 20:20:13 tneff Exp $"
X
X#include <sys/types.h>
X#include <time.h>
X#include <stdio.h>
X
X/*  The command mainline. */
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	int c;
X	int errflg = 0;
X	extern char *optarg;
X	extern int optind;
X
X	time_t when;
X	char *fmt;
X
X	char buf[1024];
X
X	int secs, mins, hrs, days, wks = 0;
X
X	/*  Collect option switches  */
X
X	while ((c = getopt(argc, argv, "s:m:h:d:w:?")) != -1)
X		switch (c)
X		{
X		case 's':
X			if ((secs = atol(optarg)) == 0)
X				errflg++;
X			break;
X		case 'm':
X			if ((mins = atol(optarg)) == 0)
X				errflg++;
X			break;
X		case 'h':
X			if ((hrs = atol(optarg)) == 0)
X				errflg++;
X			break;
X		case 'd':
X			if ((days = atol(optarg)) == 0)
X				errflg++;
X			break;
X		case 'w':
X			if ((wks = atol(optarg)) == 0)
X				errflg++;
X			break;
X
X		default:
X			errflg++;
X		}
X
X	/*  Validate args and print usage message if bad  */
X
X	switch(argc-optind)
X	{
X	case 0:
X		fmt = "%a %b %e %T %Z %Y";
X		break;
X	case 1:
X		if (argv[optind][0] == '+')
X			fmt = argv[optind]+1;
X		else
X			errflg++;
X		break;
X	default:
X		errflg++;
X	}
X
X	if (errflg)
X	{
X		fprintf(stderr, "usage: %s [-s secs] [-m mins] [-h hrs] [-d days] [-w wks] [+fmt]\n", argv[0]);
X		exit(1);
X	}
X
X	/*  Start with 'now'  */
X
X	when = time(NULL);
X
X	/*  Adjust  */
X
X	when -= secs*1;
X	when -= mins*60;
X	when -= hrs*60*60;
X	when -= days*60*60*24;
X	when -= wks*60*60*24*7;
X
X	/*  Format and output  */
X
X	cftime(buf, fmt, &when);
X	puts(buf);
X}
SHAR_EOF
fi
exit 0
#	End of shell archive

rick@pcrat.uucp (Rick Richardson) (08/22/90)

The date(1) documentation in the SVR3.2 manuals (and the SVID Issue 2)
lists a subset of the cftime(3) format specifiers as legal for printing
dates.  However, it appears that all of the cftime(3) format specifiers
work in the implementations I've tried.

The date(1) documentation should be changed to indicate that the
legal specifiers are the same as described in cftime(3).  Many
of these specifiers are truly useful in shell scripts, so I'd
hate for them to "go away" just because the SVID omitted them.

Actually, it would be superb if the date(1) command were
extended to allow both a time specification and a format
specification, so that a shell script could print a
date in the future (or past) using the format specifiers. E.G.

	$ date 0101000090 +%w
	1
	$

And to allow date arithmetic, e.g. if today is 01/01/90:

	$ date NOW-0001000000 +%m/%d/%y
	12/31/89
	$

or relative to a past or future date:

	$ date 0301000092-0001000000 +%m/%d/%y
	02/29/92
	$ date 0228000091+0001000000 +%m/%d/%y
	03/01/91
	$ date 0228000092+0001000000 +%m/%d/%y
	02/29/92
	$

-Rick

-- 
Rick Richardson | Looking for FAX software for UNIX/386 ??? Ask About: |Mention
PC Research,Inc.| FaxiX - UNIX Facsimile System (tm)                   |FAX# for
uunet!pcrat!rick| FaxJet - HP LJ PCL to FAX (Send WP,Word,Pagemaker...)|Sample
(201) 389-8963  | JetRoff - troff postprocessor for HP LaserJet and FAX|Output