/*
* strftime: print formatted information about a given time.
* Adapted from the routine by Eric R. Smith, Michal Jaegermann,
* Arnold Robins, and Paul Close.
*/
/* The authors make no claims as to the fitness or correctness of this software
* for any use whatsoever, and it is provided as is. Any use of this software
* is at the user's own risk.
*/
/* Configuration choices for %x and %X */
#undef LOCAL_DDMMYY /* choose DD/MM/YY instead of MM/DD/YY */
#undef LOCAL_DOTTIME /* choose HH.MM.SS instead of HH:MM:SS */
#include "EXTERN.h"
#include "common.h"
static char* mth_name[] = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
};
static char* day_name[] = {
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
"Saturday"
};
#ifdef HAS_FTIME
# ifndef TM_ZONE
char tznm[16] = "";
# endif
#else
extern char* tzname[];
#endif
size_t
strftime(str, maxsize, fmt, ts)
char* str;
size_t maxsize;
CONST char* fmt;
CONST struct tm* ts;
{
size_t num = 0, len;
char ch;
char* putstr;
char tmpbuf[80];
if (maxsize-- <= 0)
return 0;
for (;;) {
if (!(ch = *fmt++))
break;
if (num == maxsize) {
num = 0;
break;
}
if (ch != '%') {
*str++ = ch;
num++;
continue;
}
/* assume the finished product will be sprintf'ed into tmpbuf */
putstr = tmpbuf;
switch (ch = *fmt++) {
case 'A':
case 'a':
if (ts->tm_wday < 0 || ts->tm_wday > 6)
putstr = "?";
else
if (ch == 'A')
putstr = day_name[ts->tm_wday];
else
sprintf(tmpbuf, "%-.3s", day_name[ts->tm_wday]);
break;
case 'B':
case 'b':
case 'h':
if (ts->tm_mon < 0 || ts->tm_mon > 11)
putstr = "?";
else if (ch == 'B')
putstr = mth_name[ts->tm_mon];
else
sprintf(tmpbuf, "%-.3s", mth_name[ts->tm_mon]);
break;
case 'C':
strftime(tmpbuf, sizeof tmpbuf, "%A, %B %e, %Y", ts);
break;
case 'c':
strftime(tmpbuf, sizeof tmpbuf, "%x %X", ts);
break;
case 'D':
#ifndef LOCAL_DDMMYY
case 'x':
#endif
strftime(tmpbuf, sizeof tmpbuf, "%m/%d/%y", ts);
break;
case 'd':
sprintf(tmpbuf, "%02d", ts->tm_mday);
break;
case 'e': /* day of month, blank padded */
sprintf(tmpbuf, "%2d", ts->tm_mday);
break;
case 'H':
sprintf(tmpbuf, "%02d", ts->tm_hour);
break;
case 'I':
{
int n;
n = ts->tm_hour;
if (n == 0)
n = 12;
else if (n > 12)
n -= 12;
sprintf(tmpbuf, "%02d", n);
break;
}
case 'j':
sprintf(tmpbuf, "%03d", ts->tm_yday + 1);
break;
case 'm':
sprintf(tmpbuf, "%02d", ts->tm_mon + 1);
break;
case 'M':
sprintf(tmpbuf, "%02d", ts->tm_min);
break;
case 'p':
putstr = (ts->tm_hour < 12) ? "AM" : "PM";
break;
case 'r':
strftime(tmpbuf, sizeof tmpbuf, "%I:%M:%S %p", ts);
break;
case 'R':
strftime(tmpbuf, sizeof tmpbuf, "%H:%M", ts);
break;
case 'S':
sprintf(tmpbuf, "%02d", ts->tm_sec);
break;
case 'T':
#ifndef LOCAL_DOTTIME
case 'X':
#endif
strftime(tmpbuf, sizeof tmpbuf, "%H:%M:%S", ts);
break;
case 'U': /* week of year - starting Sunday */
sprintf(tmpbuf, "%02d", (ts->tm_yday - ts->tm_wday + 10) / 7);
break;
case 'W': /* week of year - starting Monday */
sprintf(tmpbuf, "%02d", (ts->tm_yday - ((ts->tm_wday + 6) % 7)
+ 10) / 7);
break;
case 'w':
sprintf(tmpbuf, "%d", ts->tm_wday);
break;
case 'y':
sprintf(tmpbuf, "%02d", ts->tm_year % 100);
break;
#ifdef LOCAL_DOTTIME
case 'X':
strftime(tmpbuf, sizeof tmpbuf, "%H.%M.%S", ts);
break;
#endif
#ifdef LOCAL_DDMMYY
case 'x':
strftime(tmpbuf, sizeof tmpbuf, "%d/%m/%y", ts);
break;
#endif
case 'Y':
sprintf(tmpbuf, "%d", ts->tm_year + 1900);
break;
case 'Z':
#if defined(HAS_GETTIMEOFDAY) || defined(HAS_FTIME)
# ifdef TM_ZONE
strcpy(tmpbuf, ts->tm_zone);
# else
# ifdef HAS_GETTIMEOFDAY
if (*tznm == '\0') {
char* timezone();
struct timeval tv;
struct timezone tz;
(void) gettimeofday(&tv, &tz);
strcpy(tznm, timezone(tz.tz_minuteswest, ts->tm_isdst));
}
strcpy(tmpbuf, tznm);
# else
strcpy(tmpbuf, ts->tm_name);
# endif
# endif /* !HAS_GETTIMEOFDAY */
#else /* !HAS_GETTIMEOFDAY && !HAS_FTIME */
strcpy(tmpbuf, tzname[ts->tm_isdst]);
#endif
break;
case '%':
case '\0':
putstr = "%";
break;
case 'n': /* same as \n */
putstr = "\n";
break;
case 't': /* same as \t */
putstr = "\t";
break;
default:
sprintf(tmpbuf, "%%%c", ch);
break;
}
len = strlen(putstr);
num += len;
if (num > maxsize) {
len -= num - maxsize;
num = 0;
ch = '\0';
}
strncpy(str, putstr, len);
str += len;
if (!ch)
break;
}
*str = '\0';
return num;
}
syntax highlighted by Code2HTML, v. 0.9.1