[net.sources] date+ - add specified time to date

liberte@uiucdcs.Uiuc.ARPA (07/12/85)

The recent date-oriented postings prompted me to finally get this out.  
What prompted its creation was the fact that I had to write yet another
single-purpose add-something-to-the-current-date program.  Also, I noticed a
recent posting of a script that used `at` with a "+ #" option that we do
not have.  

Now you can do things like:
	at `date+ 2 hours` < reminder
or	set lastmonth = `date+ -1 month "%y.%n"`

Date+ has more options than I know what to do with, but it's the kind of
program that needs options.  So send me your suggestions.  It is written
for Berkeley 4.2.

Daniel LaLiberte   217-333-8426
University of Illinois, Urbana-Champaign
Department of Computer Science
1304 W Springfield
Urbana, IL  61801

liberte@uiucdcs.Uiuc.ARPA
ihnp4!uiucdcs!liberte

---------free bonus--------------
Here is a one line unshar that you can apply to most shar postings
to avoid having to edit off news/notes/mail headers.
 #! /bin/sh
 # unshar - pipe shar part of input through sh
 # Ignore lines before first "#" comment starting in first column.
 # Input is either $1 or stdin.
 sed -n '/^#/,$ p' ${1-} | sh

----------------------
#! /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.
# The following files will be created:
#	date+.u
#	date+.c
# This archive created: Thu Jul 11 22:46:58 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'date+.u'" '(1786 characters)'
if test -f 'date+.u'
then
	echo shar: over-writing existing file "'date+.u'"
fi
sed 's/^X//' << \SHAR_EOF > 'date+.u'
X.TH DATE+ 1ug 
X.UC 4
X.SH NAME
Xdate+ \- print date plus specified time
X.SH SYNOPSIS
X.B date+
X[
X.I number unit
X]... [
X.I format
X]
X.SH DESCRIPTION
XThe
X.I date+
Xcommand increments the current time by the specified amount of time given
Xas several 
X.I number unit
Xpairs.  The
X.I unit
Xmay begin with
X.B sec min hour day week mon 
Xor
X.B year.
XTrailing characters are ignored.  The positive or negative floating point
X.I number
Xis truncated if the unit is month or year.
X.de mI
X.ti -4
X\\$1\ \ 
X..
X.PP
XThe optional
X.I format
Xspecifies how to print out the date and time information.
XA percent sign introduces a conversion operator;
Xthe next character specifies the desired conversion.
XOther characters are simply printed.
XThe conversion characters and their meanings are:
X.sp
X.in +6
X.mI s
Xseconds.
X.mI m
Xminutes.
X.mI h
Xhours.
X.mI d
Xday number within the month (01-31).
X.mI D
Xday number without leading zero.
X.mI n
Xmonth number (01-12).
X.mI N
Xmonth name (3 character).
X.mI y
Xyear number - 1900.
X.mI w
Xweekday number (1 is Sunday).
X.mI W
Xweekday name (3 character).
X.mI Y
Xday number within the year (1-365).
X.mI S
Xnumber of seconds since 00:00:00 GMT Jan 1, 1970.
X.in -6
X.ne 7
X.PP
XThe default format is
X.ti +2
X.nf
X"%h:%m %N %D"
X.fi
Xwhich is suitable as input to the 
X.I at (1)
Xcommand.
XNote that if the format string has any special characters
X(including spaces) then they must be protected by quoting.
X.SH EXAMPLE
X.nf
Xat `date+ 2 hours`
Xecho Time for a break > /dev/ttyme
X^D
Xdate+ -1 month "%y.%n"		# Return yy.mm for previous month
X.fi
X.SH SEE\ ALSO
X.I at (1),
X.I date (1)
X.SH AUTHOR
XDaniel LaLiberte, University of Illinois, Urbana-Champaign
X.SH BUGS
XDates that don't exist, e.g., Feb 31, can be produced by
Xadding months or years.  Producing dates before Jan 1, 1970
Xwill give strange results.
SHAR_EOF
z=`wc -c < 'date+.u'`
if test 1786 -ne $z
then
	echo shar: error transmitting "'date+.u'" \($z characters read\)
fi
echo shar: extracting "'date+.c'" '(3432 characters)'
if test -f 'date+.c'
then
	echo shar: over-writing existing file "'date+.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'date+.c'
X/* date+ - add specified time to current date */
X
X/* Please send additions, bug fixes, portifications, etc. to:
X *
X *	Daniel LaLiberte
X *	ihnp4!uiucdcs!liberte
X *	University of Illinois, Urbana-Champaign
X *	Department of Computer Science
X */
X
X/* This is written for BSD42 */
X
X#include <stdio.h>
X#include <sys/time.h>
X
Xlong tloc;
Xlong time();
X
Xchar *ctime();
Xstruct tm *localtime();
X
Xstruct tm *ts;
X
Xdouble atof();
X
X
Xint argc;	/* global argument passing */
Xchar **argv;
X
X
X
Xmain (Argc, Argv)
X/* return time + 1st arg hours */
X
Xint Argc;
Xchar *Argv[];
X
X{
X	argc = Argc;
X	argv = Argv;
X	incrdate();
X	printdate();
X
X} /* main */
X
X
X
Xincrdate()	/* increment date from arguments */
X{
X	static char *unit[] =
X	{
X		"sec", "min", "hour", "day", "week", "mon", "year", ""	};
X
X	static int conv[] =	/* conversion factor */
X	{
X		1, 60, 3600, 86400, 604800, 0, 0	};
X
X	int i;
X	double value;
X	long total;	/* cummulative total increment in whole seconds */
X	double monthincr = 0.0,	/* store increment of month and year */
X	yearincr = 0.0; 	/* since months and years are not uniform */
X
X	time(&tloc);	/* current time */
X	argc--; 
X	argv++;
X
X	while (argc &&
X	    ((**argv == '.') ||
X	    (**argv == '-') || 
X	    (**argv == '+') || 
X	    (**argv >= '0' && **argv <= '9'))) {
X		value = atof(argv[0]);
X/*		printf("%s = %f", argv[0], value); */
X
X		argv++; 
X		argc--;
X		if (argc == 0) missing();
X		else {	/* search for unit */
X			for (i = 0;	(i < 7) &&
X				(0 != strncmp(argv[0], unit[i], 
X					strlen(unit[i])));)
X				i++;
X			if (i == 7) missing();
X			else { 
X				argv++; 
X				argc--;
X				if (i < 5) value *= conv[i];
X				if (i == 5) monthincr += value;
X				if (i == 6) yearincr += value;
X			}
X/*			printf(" %s (%f seconds)\n", unit[i], value); */
X		}
X
X		total += value;
X	}
X
X
X	tloc += total;
X	ts = localtime(&tloc);
X	ts->tm_mon += monthincr;
X	ts->tm_year += yearincr;
X
X} /* getincr */
X
X
Xmissing()
X{
X	fprintf(stderr, "date+: missing unit\n");
X	exit (1);
X} 
X
X
Xprintdate()
X{
X	char *format;
X
X	static char *month[] = 
X	    {
X		"Jan", "Feb", "Mar", "Apr", "May", "Jun", 
X		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"	};
X
X	static char *day[] =
X	    {
X		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"	};
X
X
X	if (argc == 0) {	/* put default format on argv */
X		argv[0] = "%h:%m %N %D";
X		argc++;
X	}
X
X	while (argc > 0) {
X		format = argv[0];
X
X		while (*format) {
X			if (*format != '%')
X				putchar(*format);
X			else if (format[1]) 
X
X				switch(*++format) {
X				case 's': 
X					printf("%02d", ts->tm_sec);  
X					break;
X				case 'S': 
X					printf("%d", tloc);  
X					break;
X				case 'm': 
X					printf("%02d", ts->tm_min);  
X					break;
X				case 'h': 
X					printf("%02d", ts->tm_hour);  
X					break;
X				case 'd': 
X					printf("%02d", ts->tm_mday);  
X					break;
X				case 'D': 
X					printf("%d", ts->tm_mday);  
X					break;
X				case 'n': 
X					printf("%02d", ts->tm_mon + 1);  
X					break;
X				case 'N': 
X					printf("%s", month[ts->tm_mon]);  
X					break;
X				case 'y': 
X					printf("%02d", ts->tm_year);  
X					break;
X				case 'w': 
X					printf("%1d", ts->tm_wday + 1);  
X					break;
X				case 'W': 
X					printf("%s", day[ts->tm_wday]);  
X					break;
X				case 'Y': 
X					printf("%d", ts->tm_yday);  
X					break;
X
X				default:  
X					fprintf(stderr, "date+: Bad format character: '%c'\n", *format); 
X					exit(1);
X				}
X
X			format++;
X		} /* while (*format) */
X
X		argc--; 
X		argv++;
X		if (argc > 0) 
X			putchar(' ');
X	} /* while (argc > 0) */
X
X	putchar('\n');
X} /* printdate */
SHAR_EOF
z=`wc -c < 'date+.c'`
if test 3432 -ne $z
then
	echo shar: error transmitting "'date+.c'" \($z characters read\)
fi
#	End of shell archive
exit 0