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