home *** CD-ROM | disk | FTP | other *** search
- From taylor@hplabsc.UUCP Tue Jan 6 00:27:48 1987
- Path: beno!seismo!brl-adm!rutgers!sri-unix!hplabs!hplabsc!taylor
- From: taylor@hplabsc.UUCP (Dave Taylor)
- Newsgroups: net.sources
- Subject: New Date Program...
- Message-ID: <954@hplabsc.UUCP>
- Date: 6 Jan 87 05:27:48 GMT
- Reply-To: taylor@hplabsc.UUCP (Dave Taylor)
- Organization: Hewlett-Packard Labs, Palo Alto, CA
- Lines: 330
-
- So there I was after having used the date(1) command on HP-UX (System V
- with some neat enhancements, etc etc) and I got onto a Vax running BSD
- Unix. Well! The date(1) command on BSD doesn't have all the neat
- functionality that the HP-UX one has, so I rewrote the BSD date command!
- What follows is a *nonshar* (too lazy) that contains the "C" source to
- the newdate program and the man entry too.
-
- The enhancement is that the user can now specify exactly what the
- output format is to look like. You can now have 'date' output a
- format like "Today is Friday, December 12, 1986 at 4:50 pm" rather
- than the old, boring stuff. Neat, eh?
-
- This has been enhanced too - I've added (among others) %z to output the
- current timezone, so even you system V users should be interested!
-
- Bugs, etc, to comp.sources.d please.
-
- -- Dave Taylor
- taylor@hplabs.HP.COM
-
- -- attachment: shar files..
-
- # Shell Archive created by hpldat!taylor at Mon Jan 5 21:33:12 1987
-
- # To unpack the enclosed files, please use this file as input to the
- # Bourne (sh) shell. This can be most easily done by the command;
- # sh < thisfilename
-
- # This archive contains;
- # newdate.1 newdate.c
-
- # ---------- file newdate.1 ----------
-
- filename="newdate.1"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file newdate.1...
- fi
-
- cat << 'END-OF-FILE' > $filename
- .TH NEWDATE 1 LOCAL
- .UC 4
- .SH NAME
- newdate \- enhanced version of date(1)
- .SH SYNOPSIS
- .B newdate
- .RB "[ yymmddhhmm [ " . "ss ] ]"
- .br
- .B newdate
- .RB "+format_statement"
- .SH DESCRIPTION
- If no arguments are given, or the first argument doesn't start
- with a `+' character, the standard
- .I date(1)
- program is invoked.
- .sp
- If the argument begins with a `+' sign, then it is interpreted
- as follows:
- .nf
-
- %n carriage return
- %t tab
- %% percent sign
-
- %A name of the day of the week
- %D date in MM/DD/YY format
- %H hour (0-23)
- %M minute (0-59)
- %N name of the month
- %S second (0-59)
- %T time as HH:MM:SS
- %a abbreviated name of the day of the week
- %d day of month (0-31)
- %h abbreviated name of the month
- %j Julian date (0-364)
- %m month number (0-11)
- %r time as HH:MM am/pm
- %w day of week (0-6, 0=Sunday)
- %y year - 1900 (0-99)
- %z time zone name
-
- .fi
- any other characters encountered in the format instruction
- (which must start with the `+' character) are copied as
- is to the output.
- .SH EXAMPLE
- A nice date format can be obtained by using
- .nf
-
- \fInewdate "+Today is %A, %N 19%d, %y at %r'"\fR
-
- .fi
- which results in output like
- .nf
-
- \fIToday is Friday, December 12, 1986 at 11:02 pm\fR
-
- .sp
- Another interesting example is to use
- .nf
-
- \fInewdate +Date: %a %h %d, %y %T %z\fR
-
- .fi
- to get the standard mail header line:
- .nf
-
- \fIDate: Fri Dec 12, 86 23:05:40 PST\fR
-
- .fi
- .SH FILES
- /bin/date for calls to the ``real'' date program.
- .SH SEE ALSO
- date(1)
- .SH AUTHOR
- Dave Taylor, Hewlett-Packard Labs
- .SH COMPATABILITY
- This program implements the System V
- .I date(1)
- command with three new (and useful) additions,
- namely the '%A' (full day name) '%N' (full month name)
- and '%z' (time zone name).
- .SH COMMENTS
- Since this program calls
- .I /bin/date
- for all arguments other than those starting with a `+',
- it is expected that this can be called ``date'' and be
- placed somewhere in the users path so that this is the
- default program for calls to
- .I date(1).
- .sp
- The notation is really disgusting, but I'm just implementing
- what was created on System V. I suppose the correct way to
- phrase this is ``it's compatible!'', but still....
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 2140 ]
- then
- echo $filename changed - should be 2140 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- # ---------- file newdate.c ----------
-
- filename="newdate.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file newdate.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** newdate.c **/
-
- /** This program is implemented based on the manual entry in HP-UX
- (Hewlett-Packards *reliable* version of Unix) for the 'date(1)'
- program. The main improvement is that the user now has a set
- of format commands that they can use to get output in a different
- format than the normal (ugly) date(1) command. Note to system V
- and HP-UX users - I've also added %A and %N for full day and
- month name, respectively.
-
- Please see the manual entry for more information.
-
- (C) Copyright 1986, Dave Taylor
- **/
-
- /** If you're on a System V machine, then compile with -DSYSV as a flag. **/
-
- #include <stdio.h>
- #include <sys/time.h>
-
- char *short_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
- char *short_monthname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
- "Aug", "Sep", "Oct", "Nov", "Dec" };
-
- char *long_dayname[] = { "Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday" };
- char *long_monthname[] = { "January", "February", "March", "April", "May",
- "June", "July", "August", "September", "October",
- "November", "December" };
-
- struct tm *localtime(); /* forward declare for compiler happiness */
-
- #ifdef SYSV
- extern char *tzname[2];
- #else
- char *timezone(); /* another forward declaration... */
- #endif
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char buffer[200], /* our output buffer... */
- tempbuf[100]; /* and a temp one for formatting stuff */
- int loc; /* our location in the format string */
- long thetime; /* the current time, in seconds! */
- struct tm *t; /* the time record structure */
- #ifndef SYSV
- struct timeval tp; /* for storing yet-another-format */
- struct timezone tz; /* to figure out our timezone... */
- #endif
-
- if (argc == 1 || argv[1][0] != '+') /* go to 'real' date prog */
- execv("/bin/date", argv);
-
- if (argc > 2) {
- fprintf(stderr,"Usage: %s [new time] [ + format string]\n",
- argv[0]);
- exit(1);
- }
-
- /* if we're here we're doing okay... */
-
- thetime = time( (long *) 0);
- t = localtime(&thetime);
-
- #ifndef SYSV
- /** now let's get the timezone that we're in... **/
-
- gettimeofday(&tp, &tz);
-
- #endif
-
- /* we have the time...now let's parse and build the output! */
-
- for (loc = 1; loc < strlen(argv[1]);) {
- tempbuf[0] = '\0';
-
- if (argv[1][loc] == '%') { /* a format string! */
-
- switch (argv[1][loc+1]) {
-
- case 'n' : strcat(buffer, "\n"); break;
- case 't' : strcat(buffer, "\t"); break;
- case '%' : strcat(buffer, "%"); break;
-
- case 'm' : sprintf(tempbuf, "%d", t->tm_mon); break;
- case 'd' : sprintf(tempbuf, "%d", t->tm_mday); break;
- case 'y' : sprintf(tempbuf, "%d", t->tm_year); break;
- case 'D' : sprintf(tempbuf, "%d/%d/%d",
- t->tm_mon, t->tm_mday, t->tm_year); break;
- case 'H' : sprintf(tempbuf, "%d", t->tm_hour); break;
- case 'M' : sprintf(tempbuf, "%d", t->tm_min); break;
- case 'S' : sprintf(tempbuf, "%d", t->tm_sec); break;
- case 'T' : sprintf(tempbuf, "%02d:%02d:%02d",
- t->tm_hour, t->tm_min, t->tm_sec); break;
- case 'j' : sprintf(tempbuf, "%d", t->tm_yday); break;
- case 'w' : sprintf(tempbuf, "%d", t->tm_wday); break;
- case 'a' : sprintf(tempbuf, "%s",
- short_dayname[t->tm_wday]); break;
- case 'h' : sprintf(tempbuf, "%s",
- short_monthname[t->tm_mon]); break;
- case 'A' : sprintf(tempbuf, "%s",
- long_dayname[t->tm_wday]); break;
- case 'N' : sprintf(tempbuf, "%s",
- long_monthname[t->tm_mon]); break;
- case 'r' : sprintf(tempbuf, "%d:%02d %s",
- t->tm_hour > 12? t->tm_hour - 12:t->tm_hour,
- t->tm_min,
- t->tm_hour > 12? "pm":"am"); break;
- case 'z' : sprintf(tempbuf, "%s",
- #ifdef SYSV
- t->tm_isdst? tzname[1] : tzame[0]); break;
- #else
- timezone(tz.tz_minuteswest, t->tm_isdst)); break;
- #endif
-
- case '\0': fprintf(stderr,
- "%s: unexpected end of format instructions!\n",argv[0]);
- exit(1);
-
- default : fprintf(stderr,
- "%s: don't understand %%%c as a format instruction!\n",
- argv[0], argv[1][loc+1]);
- exit(1);
- }
-
- loc += 2; /* skip the percent and the char we just dealt with */
-
- if (tempbuf[0] != '\0')
- strcat(buffer, tempbuf);
-
- }
- else { /* not a percent sign... */
-
- tempbuf[0] = argv[1][loc++];
- tempbuf[1] = '\0';
- strcat(buffer, tempbuf);
-
- }
- }
-
- /* and print the buffer out! */
-
- printf("%s\n", buffer);
-
- exit(0); /* bye! */
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 4546 ]
- then
- echo $filename changed - should be 4546 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- echo done
-
- exit 0
-
-
-