Listing 5 xgentime.c

/* _Gentime function */
#include "xtime.h"

              /* macros */
#define SUNDAY  0        /* codes for tm_wday */
#define MONDAY  1

static char *getval(char *s, int val, int n)
       {       /* convert a decimal value */
       if (val < 0)
              val = 0;
       for (s += n, *s = '\0'; 0 <= --n; val /= 10)
              *--s = val % 10 + '0';
       return (s);
       }

static int wkyr(int wstart, int wday, int yday)
       {       /* find week of year */
       wday = (wday + 7 - wstart) % 7;
       return (yday - wday + 12) / 7 - 1;
       }

const char *_Gentime(const struct tm *t,
       _Tinfo *tin, const char *s, int *pn, char *ac)
       {       /* format a time field */
       const char *p;
       
       switch (*s++)
              {       /* switch on conversion specifier */
       case 'a':       /* put short weekday name */
              p = _Gettime(tin->_Days, t->tm_wday << 1, pn);
              break;
       case 'A':       /* put full weekday name */
              p = _Gettime(tin->_Days, (t->tm_wday << 1) + 1, pn);
              break;
       case 'b':       /* put short month name */
              p = _Gettime(tin->_Months, t->tm_mon << 1, pn);
              break;
       case 'B':       /* put full month name */
              p = _Gettime(tin->_Months, (t->tm_mon << 1) + 1, pn);
              break;
       case 'c':       /* put date and time */
              p = _Gettime(tin->_Formats, 0, pn),
                     *pn = -*pn;
              break;
       case 'd':       /* put day of month, from 01 */
              p = getval(ac, t->tm_mday, *pn = 2);
              break;
       case 'D':       /* put day of month, from 1 */
              p = getval(ac, t->tm_mday, *pn = 2);
              if (ac[0] == '0')
                     ac [0] = ' ';
              break;
       case 'H':       /* put hour of 24-hour day */
              p = getval(ac, t->tm_hour, *pn = 2);
              break;
       case 'I':       /* put hour of 12-hour day */
              p = getval(ac, t->tm_hour % 12, *pn = 2);
              break;
       case 'j':       /* put day of year, from 001 */
              p = getval(ac, t->tm_yday + 1, *pn = 3);
              break;
       case 'm':       /* put month of year, from 01 */
              p = getval(ac, t->tm_mon + 1, *pn = 2);
              break;
       case 'M':       /* put minutes after the hour */
              p = getval(ac, t->tm_min, *pn = 2);
              break;
       case 'p':       /* put AM/PM */
              p = _Gettime(tin->_Ampm, 12 <= t->tm_hour, pn);
              break;
       case 'S':       /* put seconds after the minute */
              p = getval(ac, t->tm_sec, *pn = 2);
              break;
       case 'U':       /* put Sunday week of the year */
              p = getval(ac,
                     wkyr(SUNDAY, t->tm_wday, t->tm_yday),
                     *pn = 2);
              break;
       case 'w':       /* put day of week, from Sunday */
              p = getval(ac, t->tm_wday, *pn = 1);
              break;
       case 'W':       /* put Monday week of the year */
              p = getval(ac,
                     wkyr(MONDAY, t->tm_wday, t->tm_yday),
                     *pn = 2);
              break;
       case 'x':       /* put date */
              p =_Gettime(tin->_Formats, 1, pn),
                     *pn = -*pn;
              break;
       case 'X':       /* put time */
              p = _Gettime(tin->_Formats, 2, pn),
                     *pn = -*pn;
              break;
       case 'y':       /* put year of the century */
              p = getval(ac, t->tm_year % 100, *pn = 2);
              break;
       case 'Y':       /* put year */
              p = getval(ac, t->tm_year + 1900, *pn = 4);
              break;
       case 'Z':       /* put time zone name */
              if (tin->_Tzone[0] == '\0')
                     tin->_Tzone = _Getzone();  /* adapt zone */
              p = _Gettime(tin->_Tzone, 0 < t->tm_isdst, pn);
              break;
       case '%':       /* put "%" */
              p = "%", *pn = 1;
              break;
       default:        /* unknown field, print it */
              p = s - 1, *pn = 2;
              }
       return (p);
       }

/* End of File */