home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / XBBS7200.ZIP / XBBS7200.TAR / today / today.c < prev   
Encoding:
C/C++ Source or Header  |  1986-10-02  |  9.8 KB  |  367 lines

  1. /*
  2.  *            T O D A Y
  3.  *
  4.  * time of day
  5.  *
  6.  * Define UNIX for "native" Unix
  7.  */
  8.  
  9. /*)BUILD    $(PROGRAM)    = today
  10.         $(FILES)    = { today datetx timetx nbrtxt moontx }
  11.         $(TKBOPTIONS)    = {
  12.             TASK    = ...TOD
  13.         }
  14. */
  15.  
  16. #ifdef    DOCUMENTATION
  17.  
  18. title    today    Date and Time in English
  19. index        Date and Time in English
  20.  
  21. synopsis
  22.  
  23.     today [-] [x] | [date]
  24.  
  25. description
  26.  
  27.     Today prints the date, time, and phase of the moon in English.
  28.     The following options are available:
  29.     .lm +8
  30.     .s.i -8;- or x    Read date strings from the standard input file.
  31.     .s.i -8;date    Print information for the indicated date.
  32.     .s.lm -8
  33.     Date and time information is given in ISO numeric notation.  For
  34.     example, November 6, 1980 would be represented as "801106".  If
  35.     a time is needed, it would be appended to the date, using 24-hour
  36.     notation: "801106110402" would be a time which is exact to the
  37.     second.  To specify the century, the two-digit century number
  38.     may be preceeded by '+' as in "+18801106".
  39.     .s
  40.     Non-numeric separators between the various fields are permitted:
  41.     "+1776.07.04-11:15:21".  Note that the full two digit entry must be
  42.     given.
  43.     .s
  44.     If no parameter is given, today outputs the current date and time.
  45.  
  46. diagnostics
  47.  
  48.     .lm +8
  49.     .s.i -8;Bad parameters or date out of range in ...
  50.     .s
  51.     An input date or time is incorrect.
  52.     .lm -8
  53.  
  54. author
  55.  
  56.     Martin Minow
  57.  
  58. bugs
  59.  
  60.     The algorithm is only valid for the Gregorian calender.
  61.  
  62. #endif
  63.  
  64. #define    APRIL_FOOLS
  65.  
  66. int    __narg    =    1;        /* No prompt if no args        */
  67. #define LINEWIDTH       72              /* Width of line                */
  68.  
  69. #include <stdio.h>
  70. #include <time.h>
  71. #include <ctype.h>
  72. #undef NULL
  73.  
  74. #define    NULL        0
  75. #define    EOS        0
  76. #define    FALSE        0
  77. #define    TRUE        1
  78.  
  79. int day_month[] = {            /* Needed for dotexttime()      */
  80.     0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  81. };
  82. int     ccpos;                          /* Current line position        */
  83. char    lastbyte;                       /* Memory for output()          */
  84. char    line[100];                      /* Data line for input function */
  85. char    *valptr;                        /* Needed for number converter  */
  86. char    wordbuffer[LINEWIDTH];          /* Buffer for output function   */
  87. char    *wordptr = wordbuffer;          /* Free byte in wordbuffer      */
  88. char    linebuffer[LINEWIDTH+2];    /* Output text buffer        */
  89. char    *lineptr = linebuffer;        /* Free byte in linebuffer    */
  90. int     polish;                         /* Funny mode flag              */
  91. int    sunrise;            /* Sunrise print flag        */
  92.  
  93. extern  char    *datetxt();             /* Date getter                  */
  94. extern  char    *timetxt();             /* Time of day getter           */
  95. extern  char    *moontxt();             /* Phase of the moon getter     */
  96.  
  97. main(argc, argv)
  98. int     argc;
  99. char    *argv[];
  100. /*
  101.  * Driver for time routines.  Usage:
  102.  *
  103.  *      today                   Prints current time of day in readable form,
  104.  *                              followed by a cookie.
  105.  *
  106.  *      today {+cc}yymmddhhmmss Prints indicated time of day.
  107.  *                              Note, hh, mm, ss may be omitted.
  108.  *                              For example:
  109.  *                                today 401106     = Nov. 6, 1940
  110.  *                                today +19401106  = Nov. 6, 1940
  111.  *                                today 4011061015 = Nov. 6, 1940 10:15 AM
  112.  *
  113.  *      today -                 Data is read from the standard input and
  114.  *      today x                 output as needed.  The format of each
  115.  *                              line is identical to the command format.
  116.  *                ("today x" is needed for vms.)
  117.  */
  118.  
  119. {
  120.     ccpos = 0;                      /* New line now                 */
  121.     wordptr = wordbuffer;           /* Nothing buffered             */
  122.     lineptr = linebuffer;        /* Nothing in output buffer too    */
  123.     polish = 0;            /* Normal mode            */
  124.     if (argc > 1 && tolower(argv[1][0]) == 'p') {
  125.         polish = 1;
  126.         argc--;
  127.         argv++;
  128.     }
  129.     sunrise = 0;
  130.     if (argc > 1 && tolower(argv[1][0]) == 's') {
  131.         sunrise = 1;
  132.         argc--;
  133.         argv++;
  134.     }
  135.  
  136.     if (argc == 1) sunrise = 1;
  137.  
  138.     if (argc == 2 && ((argv[1][0] == '-') || (argv[1][0] | 040) == 'x')) {
  139.         while (!getline()) {    /* Read and print times */
  140.             dotexttime(line);
  141.         }
  142.         return;
  143.     }
  144.     else if (argc > 1) {
  145.         if (dotexttime(argv[1]) == 0)
  146.             return;
  147.     }
  148.     /*
  149.      * Here if no parameters or an error in the parameter field.
  150.      */
  151.     dotime();            /* Print the time.              */
  152.     output("\n");               /* Space before cookie          */
  153. #ifdef    UNIX
  154.     execl(COOKIEPROGRAM, "cookie", 0);
  155. #endif
  156. }
  157.  
  158. dotime()
  159. /*
  160.  * Print the time of day for Unix or VMS native mode.
  161.  */
  162. {
  163.     long    tvec;                   /* Buffer for time function     */
  164.     struct  tm *localtime();    /* Unix time decompile function */
  165.     struct  tm *p;            /* Local pointer to time of day */
  166.     int     year;
  167.     int     month;
  168.  
  169.     time(&tvec);                     /* Get the time of day          */
  170.     p = localtime(&tvec);           /* Make it more understandable  */
  171.     year = p->tm_year + 1900;
  172.     month = p->tm_mon + 1;
  173. #ifdef    APRIL_FOOLS
  174.     if (month == 4 && p->tm_mday == 1)
  175.         polish = !polish;
  176. #endif
  177.     process(year, month, p->tm_mday, p->tm_hour,
  178.              p->tm_min, p->tm_sec, p->tm_isdst);
  179. }
  180.  
  181. dotexttime(text)
  182. char    *text;                          /* Time text                    */
  183. /*
  184.  * Create the time values and print them, return 1 on error.
  185.  */
  186.  
  187. {
  188.     int     epoch;                  /* Which century                */
  189.     int     year;
  190.     int     month;
  191.     int     day;
  192.     int     hour;
  193.     int     minute;
  194.     int     second;
  195.     int     leapyear;
  196.  
  197.     valptr = text;                          /* Setup for getval()   */
  198.     while (*valptr == ' ') valptr++;        /* Leading blanks skip  */
  199.     if (*valptr != '+')
  200.         epoch = 1900;                   /* Default for now      */
  201.     else {
  202.         valptr++;
  203.         if ((epoch = getval(-1, 00, 99)) < 0) goto bad;
  204.         epoch *= 100;                   /* Make it a real epoch */
  205.     }
  206.  
  207.     if ((year = getval(-1, 00, 99)) < 0) goto bad;
  208.     year += epoch;
  209.     leapyear = ((year%4) == 0) && (((year%400) == 0) || (year%100 != 0));
  210.     if ((month = getval(-1, 1, 12)) < 0) goto bad;
  211.     if ((day = getval(-1, 1,
  212.         (month == 2 && leapyear) ? 29 : day_month[month])) < 0)
  213.             goto bad;
  214.     if ((hour = getval(-2, 0, 23)) == -1) goto bad;
  215.     if ((minute = getval(-2, 0, 59)) == -1) goto bad;
  216.     if ((second = getval(-2, 0, 59)) == -1) goto bad;
  217.     process(year, month, day, hour, minute, second, 0);
  218.     return(0);                /* Normal exit        */
  219.  
  220. bad:    output("Bad parameters or date out of range in \"");
  221.     output(text);
  222.     output("\" after scanning \"");
  223.     *valptr = '\0';
  224.     output(text);
  225.     output("\".\n");
  226.     return(1);                /* Error exit        */
  227. }
  228.  
  229. static    char    outline[500];        /* Output buffer                */
  230.  
  231. process(year, month, day, hour, minute, second, daylight)
  232. int     year;                           /* Year        1900 = 1900    */
  233. int     month;                          /* Month    January = 1    */
  234. int     day;                            /* Day        1 = 1        */
  235. int    hour;                /* Hour        0 .. 23        */
  236. int    minute;                /* Minute    0 .. 59        */
  237. int    second;                /* Second    0 .. 59        */
  238. int    daylight;            /* Daylight savings time if 1    */
  239. /*
  240.  * Output the information.  Note that the parameters are within range.
  241.  */
  242. {
  243.  
  244.     output("Today is ");
  245.     datetxt(outline, year, month, day);
  246.     output(outline);
  247.     output(".  ");
  248.     timetxt(outline, hour, minute, second,
  249.             (polish) ? 0101010 : daylight);
  250.     output(outline);
  251.     if (sunrise) {
  252.       int sunrh, sunrm, sunsh, sunsm;
  253.       sun(&sunrh, &sunrm, &sunsh, &sunsm);
  254.       output("Sunrise is at ");
  255.       timetxt(outline, sunrh, sunrm, -2, -1);
  256.       output(outline);
  257.       output("; sunset is at ");
  258.       timetxt(outline, sunsh, sunsm, -2, -1);
  259.       output(outline);
  260.       output(".  ");
  261.       }
  262. /*    output("The moon is ");            */
  263. /*    moontxt(outline, year, month, day);    */
  264.     moontxt(outline);    /* replaced by smarter version */
  265.     output(outline);
  266.     output(".\n");
  267.  
  268. }
  269.  
  270.  
  271. output(text)
  272. char    *text;                                  /* What to print        */
  273. /*
  274.  * Output routine.  Text is output using put() so that lines are
  275.  * not more than LINEWIDTH bytes long.  Current position is in global ccpos.
  276.  * (put is equivalent to putchar() except that it is locally buffered.)
  277.  */
  278. {
  279.     register char    *in;                    /* Current pos. in scan */
  280.     register char    c;                      /* Current character    */
  281.     register char    *wp;            /* Word pointer        */
  282.  
  283.     in = text;
  284.     while (c = *in++) {
  285.         switch (c) {
  286.         case '\n':                      /* Force new line       */
  287.         case ' ':                       /* or a space seen      */
  288.             if ((wordptr-wordbuffer) + ccpos >= LINEWIDTH) {
  289.                 put('\n');  /* Current word         */
  290.                 ccpos = 0;      /* won't fit, dump it.  */
  291.             }
  292.             if (wordptr > wordbuffer) {
  293.                 if (ccpos) {    /* Leading space needed */
  294.                     put(' ');
  295.                     ccpos++;
  296.                 }
  297.                 for (wp = wordbuffer; wp < wordptr;) {
  298.                     put(*wp++);
  299.                 }
  300.                 ccpos += (wordptr - wordbuffer);
  301.                 wordptr = wordbuffer;    /* Empty buffer    */
  302.             }
  303.             if (c == '\n') {
  304.                 put('\n');    /* Print a newline    */
  305.                 ccpos = 0;    /* and reset the cursor    */
  306.             }
  307.             break;
  308.  
  309.         default:
  310.             *wordptr++ = c;         /* Save piece of word   */
  311.         }
  312.     }
  313. }
  314.  
  315. put(c)
  316. register char    c;
  317. /*
  318.  * Actual output routine
  319.  */
  320. {
  321.     if (c == '\n' || (lineptr - linebuffer) >= LINEWIDTH) {
  322.         *lineptr = EOS;
  323.         puts(linebuffer);
  324.         lineptr = linebuffer;
  325.         if (c == '\n')
  326.             return;
  327.     }
  328.     *lineptr++ = c;
  329.  
  330. getline()
  331. /*
  332.  * Read text to global line[].  Return 1 on end of file, zero on ok.
  333.  */
  334. {
  335.     register char *t;
  336.  
  337.     return (gets(line) == NULL);
  338. }
  339.  
  340. getval(flag, low, high)
  341. int     flag;
  342. int     low;
  343. int     high;
  344. /*
  345.  * Global valptr points to a 2-digit positive decimal integer.
  346.  * Skip over leading non-numbers and return the value.
  347.  * Return flag if text[0] == '\0'. Return -1 if the text is bad,
  348.  * or if the value is out of the low:high range.
  349.  */
  350. {
  351.     register int value;
  352.     register int i;
  353.     register int temp;
  354.  
  355.     if (*valptr == '\0') return(flag);        /* Default?             */
  356.     while (*valptr && (*valptr < '0' || *valptr > '9')) *valptr++;
  357.                 /* The above allows for 78.04.22 format */
  358.     for (value = i = 0; i < 2; i++) {
  359.         temp = *valptr++ - '0';
  360.         if (temp < 0 || temp > 9) return(-1);
  361.         value = (value*10) + temp;
  362.     }
  363.     return((value >= low && value <= high) ? value : -1);
  364. }
  365.  
  366.