home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / netsrcs / date < prev    next >
Internet Message Format  |  1987-01-07  |  9KB

  1. From taylor@hplabsc.UUCP Tue Jan  6 00:27:48 1987
  2. Path: beno!seismo!brl-adm!rutgers!sri-unix!hplabs!hplabsc!taylor
  3. From: taylor@hplabsc.UUCP (Dave Taylor)
  4. Newsgroups: net.sources
  5. Subject: New Date Program...
  6. Message-ID: <954@hplabsc.UUCP>
  7. Date: 6 Jan 87 05:27:48 GMT
  8. Reply-To: taylor@hplabsc.UUCP (Dave Taylor)
  9. Organization: Hewlett-Packard Labs, Palo Alto, CA
  10. Lines: 330
  11.  
  12. So there I was after having used the date(1) command on HP-UX (System V
  13. with some neat enhancements, etc etc) and I got onto a Vax running BSD
  14. Unix.  Well!  The date(1) command on BSD doesn't have all the neat
  15. functionality that the HP-UX one has, so I rewrote the BSD date command!
  16. What follows is a *nonshar* (too lazy) that contains the "C" source to
  17. the newdate program and the man entry too.
  18.  
  19. The enhancement is that the user can now specify exactly what the
  20. output format is to look like.  You can now have 'date' output a
  21. format like "Today is Friday, December 12, 1986 at 4:50 pm" rather
  22. than the old, boring stuff.  Neat, eh?
  23.  
  24. This has been enhanced too - I've added (among others) %z to output the
  25. current timezone, so even you system V users should be interested!
  26.  
  27. Bugs, etc, to comp.sources.d please.
  28.  
  29.                         -- Dave Taylor
  30.                         taylor@hplabs.HP.COM
  31.  
  32. -- attachment: shar files..
  33.  
  34. # Shell Archive created by hpldat!taylor at Mon Jan  5 21:33:12 1987
  35.  
  36. # To unpack the enclosed files, please use this file as input to the
  37. # Bourne (sh) shell.  This can be most easily done by the command;
  38. #     sh < thisfilename
  39.  
  40. # This archive contains;
  41. #  newdate.1        newdate.c
  42.  
  43. # ---------- file newdate.1 ----------
  44.  
  45. filename="newdate.1"
  46.  
  47. if [ -f $filename ]
  48. then
  49.   echo File \"$filename\" already exists\!  Skipping...
  50.   filename=/dev/null        # throw it away
  51. else
  52.   echo extracting file newdate.1...
  53. fi
  54.  
  55. cat << 'END-OF-FILE' > $filename
  56. .TH NEWDATE 1 LOCAL
  57. .UC 4
  58. .SH NAME
  59. newdate \- enhanced version of date(1)
  60. .SH SYNOPSIS
  61. .B newdate
  62. .RB "[ yymmddhhmm [ " . "ss ] ]"
  63. .br
  64. .B newdate
  65. .RB "+format_statement"
  66. .SH DESCRIPTION
  67. If no arguments are given, or the first argument doesn't start
  68. with a `+' character, the standard 
  69. .I date(1)
  70. program is invoked.  
  71. .sp
  72. If the argument begins with a `+' sign, then it is interpreted
  73. as follows:
  74. .nf
  75.  
  76.     %n    carriage return
  77.     %t    tab
  78.     %%    percent sign
  79.     
  80.     %A    name of the day of the week
  81.     %D    date in MM/DD/YY format
  82.     %H    hour (0-23)
  83.     %M    minute (0-59)
  84.     %N    name of the month
  85.     %S    second (0-59)
  86.     %T    time as HH:MM:SS
  87.     %a    abbreviated name of the day of the week
  88.     %d    day of month (0-31)
  89.     %h    abbreviated name of the month
  90.     %j    Julian date (0-364)
  91.     %m    month number (0-11)
  92.     %r    time as HH:MM am/pm
  93.     %w    day of week (0-6, 0=Sunday)
  94.     %y    year - 1900  (0-99)
  95.     %z    time zone name
  96.  
  97. .fi
  98. any other characters encountered in the format instruction
  99. (which must start with the `+' character) are copied as
  100. is to the output.
  101. .SH EXAMPLE
  102. A nice date format can be obtained by using
  103. .nf
  104.  
  105.   \fInewdate "+Today is %A, %N 19%d, %y at %r'"\fR
  106.  
  107. .fi
  108. which results in output like
  109. .nf
  110.  
  111.   \fIToday is Friday, December 12, 1986 at 11:02 pm\fR
  112.  
  113. .sp
  114. Another interesting example is to use
  115. .nf
  116.  
  117.   \fInewdate +Date: %a %h %d, %y %T %z\fR
  118.  
  119. .fi
  120. to get the standard mail header line:
  121. .nf
  122.  
  123.   \fIDate: Fri Dec 12, 86 23:05:40 PST\fR
  124.  
  125. .fi
  126. .SH FILES
  127. /bin/date for calls to the ``real'' date program.
  128. .SH SEE ALSO
  129. date(1)
  130. .SH AUTHOR
  131. Dave Taylor, Hewlett-Packard Labs
  132. .SH COMPATABILITY
  133. This program implements the System V 
  134. .I date(1)
  135. command with three new (and useful) additions,
  136. namely the '%A' (full day name) '%N' (full month name)
  137. and '%z' (time zone name).
  138. .SH COMMENTS
  139. Since this program calls 
  140. .I /bin/date
  141. for all arguments other than those starting with a `+',
  142. it is expected that this can be called ``date'' and be
  143. placed somewhere in the users path so that this is the
  144. default program for calls to 
  145. .I date(1).
  146. .sp
  147. The notation is really disgusting, but I'm just implementing
  148. what was created on System V.  I suppose the correct way to
  149. phrase this is ``it's compatible!'', but still....
  150. END-OF-FILE
  151.  
  152. if [ "$filename" != "/dev/null" ]
  153. then
  154.   size=`wc -c < $filename`
  155.  
  156.   if [ $size != 2140 ]
  157.   then
  158.     echo $filename changed - should be 2140 bytes, not $size bytes
  159.   fi
  160.  
  161.   chmod 666 $filename
  162. fi
  163.  
  164. # ---------- file newdate.c ----------
  165.  
  166. filename="newdate.c"
  167.  
  168. if [ -f $filename ]
  169. then
  170.   echo File \"$filename\" already exists\!  Skipping...
  171.   filename=/dev/null        # throw it away
  172. else
  173.   echo extracting file newdate.c...
  174. fi
  175.  
  176. cat << 'END-OF-FILE' > $filename
  177. /**                newdate.c                **/
  178.  
  179. /** This program is implemented based on the manual entry in HP-UX
  180.     (Hewlett-Packards *reliable* version of Unix) for the 'date(1)'
  181.     program.  The main improvement is that the user now has a set
  182.     of format commands that they can use to get output in a different
  183.     format than the normal (ugly) date(1) command.  Note to system V
  184.     and HP-UX users - I've also added %A and %N for full day and
  185.     month name, respectively.
  186.  
  187.     Please see the manual entry for more information.
  188.  
  189.     (C) Copyright 1986, Dave Taylor
  190. **/
  191.  
  192. /** If you're on a System V machine, then compile with -DSYSV as a flag. **/
  193.  
  194. #include <stdio.h>
  195. #include <sys/time.h>
  196.  
  197. char *short_dayname[]   = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
  198. char *short_monthname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
  199.                     "Aug", "Sep", "Oct", "Nov", "Dec" };
  200.  
  201. char *long_dayname[]    = { "Sunday", "Monday", "Tuesday", "Wednesday", 
  202.                 "Thursday", "Friday", "Saturday" };
  203. char *long_monthname[]  = { "January", "February", "March", "April", "May",
  204.                 "June", "July", "August", "September", "October",
  205.                 "November", "December" };
  206.  
  207. struct tm *localtime();        /* forward declare for compiler happiness */
  208.  
  209. #ifdef SYSV
  210.   extern char *tzname[2];
  211. #else
  212.   char *timezone();        /* another forward declaration...      */
  213. #endif
  214.  
  215. main(argc, argv)
  216. int argc;
  217. char *argv[];
  218. {
  219.     char buffer[200],     /* our output buffer...         */
  220.          tempbuf[100];    /* and a temp one for formatting stuff  */
  221.     int  loc;        /* our location in the format string    */
  222.     long thetime;        /* the current time, in seconds!        */
  223.     struct tm *t;        /* the time record structure        */
  224. #ifndef SYSV
  225.     struct timeval    tp;    /* for storing yet-another-format       */
  226.     struct timezone tz;    /* to figure out our timezone...        */
  227. #endif
  228.  
  229.     if (argc == 1 || argv[1][0] != '+')   /* go to 'real' date prog */
  230.       execv("/bin/date", argv);
  231.  
  232.     if (argc > 2) {
  233.       fprintf(stderr,"Usage: %s [new time] [ + format string]\n",
  234.           argv[0]);
  235.       exit(1);
  236.     }
  237.  
  238.     /* if we're here we're doing okay... */
  239.  
  240.     thetime = time( (long *) 0);
  241.     t = localtime(&thetime);
  242.  
  243. #ifndef SYSV
  244.     /** now let's get the timezone that we're in... **/
  245.  
  246.     gettimeofday(&tp, &tz);
  247.  
  248. #endif
  249.  
  250.     /* we have the time...now let's parse and build the output! */
  251.  
  252.     for (loc = 1; loc < strlen(argv[1]);) {
  253.       tempbuf[0] = '\0';
  254.  
  255.       if (argv[1][loc] == '%') {    /* a format string! */
  256.  
  257.         switch (argv[1][loc+1]) {
  258.  
  259.           case 'n' : strcat(buffer, "\n");        break;
  260.           case 't' : strcat(buffer, "\t");        break;
  261.           case '%' : strcat(buffer, "%");        break;
  262.  
  263.           case 'm' : sprintf(tempbuf, "%d", t->tm_mon);    break;
  264.           case 'd' : sprintf(tempbuf, "%d", t->tm_mday);    break;
  265.           case 'y' : sprintf(tempbuf, "%d", t->tm_year);    break;
  266.           case 'D' : sprintf(tempbuf, "%d/%d/%d",
  267.              t->tm_mon, t->tm_mday, t->tm_year);    break;
  268.           case 'H' : sprintf(tempbuf, "%d", t->tm_hour);    break;
  269.           case 'M' : sprintf(tempbuf, "%d", t->tm_min);    break;
  270.           case 'S' : sprintf(tempbuf, "%d", t->tm_sec);    break;
  271.           case 'T' : sprintf(tempbuf, "%02d:%02d:%02d",
  272.              t->tm_hour, t->tm_min, t->tm_sec);    break;
  273.           case 'j' : sprintf(tempbuf, "%d", t->tm_yday);    break;
  274.           case 'w' : sprintf(tempbuf, "%d", t->tm_wday);    break;
  275.           case 'a' : sprintf(tempbuf, "%s", 
  276.                  short_dayname[t->tm_wday]);     break;
  277.           case 'h' : sprintf(tempbuf, "%s", 
  278.                 short_monthname[t->tm_mon]);     break;
  279.           case 'A' : sprintf(tempbuf, "%s", 
  280.                  long_dayname[t->tm_wday]);     break;
  281.           case 'N' : sprintf(tempbuf, "%s", 
  282.                 long_monthname[t->tm_mon]);     break;
  283.           case 'r' : sprintf(tempbuf, "%d:%02d %s",
  284.              t->tm_hour > 12? t->tm_hour - 12:t->tm_hour,
  285.                  t->tm_min,
  286.              t->tm_hour > 12? "pm":"am");        break;
  287.           case 'z' : sprintf(tempbuf, "%s",
  288. #ifdef SYSV
  289.              t->tm_isdst? tzname[1] : tzame[0]);    break;
  290. #else
  291.              timezone(tz.tz_minuteswest, t->tm_isdst));  break;
  292. #endif
  293.  
  294.           case '\0': fprintf(stderr,
  295.             "%s: unexpected end of format instructions!\n",argv[0]);
  296.              exit(1);
  297.  
  298.           default  : fprintf(stderr,
  299.                  "%s: don't understand %%%c as a format instruction!\n",
  300.              argv[0], argv[1][loc+1]);
  301.              exit(1);
  302.         }
  303.  
  304.         loc += 2;    /* skip the percent and the char we just dealt with */
  305.  
  306.         if (tempbuf[0] != '\0') 
  307.           strcat(buffer, tempbuf);
  308.  
  309.       }
  310.       else {     /* not a percent sign... */
  311.  
  312.         tempbuf[0] = argv[1][loc++];
  313.         tempbuf[1] = '\0';
  314.         strcat(buffer, tempbuf);
  315.  
  316.       }
  317.     }
  318.     
  319.     /* and print the buffer out! */
  320.  
  321.     printf("%s\n", buffer);
  322.     
  323.     exit(0);            /* bye! */
  324. }
  325. END-OF-FILE
  326.  
  327. if [ "$filename" != "/dev/null" ]
  328. then
  329.   size=`wc -c < $filename`
  330.  
  331.   if [ $size != 4546 ]
  332.   then
  333.     echo $filename changed - should be 4546 bytes, not $size bytes
  334.   fi
  335.  
  336.   chmod 666 $filename
  337. fi
  338.  
  339. echo done
  340.  
  341. exit 0
  342.  
  343.  
  344.