#include <u.h>
#include <libc.h>
char *format_t(char *, Tm);
ulong now;
char *month[]=
{
"January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December",
};
char *dayname[]=
{
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday",
};
void
usage(void)
{
fprint(2, "usage: %s [-t seconds] format\n", argv0);
exits("usage");
}
void
main(int argc, char *argv[])
{
Tm *now_tm;
now = time(0);
ARGBEGIN{
case 't':
now = strtoul(EARGF(usage()), 0, 0);
break;
default:
usage();
}ARGEND
if(! argc == 1) {
usage();
}
now_tm = localtime(now);
print("%s", format_t(argv[0], *now_tm));
exits(0);
}
char *
format_t(char *format, Tm t)
{
char *outb;
int i, n;
Rune r;
outb="";
for(i = 0; i < strlen(format); i++){
if(format[i] != '%') {
n=chartorune(&r, &format[i]);
i=i+(n-1);
outb=smprint("%s%C", outb, r);
}
else switch(format[++i]){
/*
* There's a lot of these. I've done most of POSIX except
* locales (EO) and the year-by-weeks stuff (gGUVW), plus.
* here: aAbBcCdDe F hHIjklmMn prRsStTu v w xXyYzZ%+ ,.
* C89: aAbBc d HIj mM p S U wWxXyY Z%
* C04: aAbBcCdDeEFgGhHIj mM OprR S TuU VwWxXyYzZ%
* OS X: aAbBcCdDeEFgGhHIjklmMnOprRsStTuUvVwWxXyYzZ%+
* Intentionally "stuck" in "C locale".
*/
case 'a':
outb=smprint("%s%.3s", outb, format_t("%A", t));
break;
case 'A':
outb=smprint("%s%s", outb, dayname[t.wday]);
break;
case 'b':
outb=smprint("%s%.3s", outb, format_t("%B", t));
break;
case 'B':
outb=smprint("%s%s", outb, month[t.mon]);
break;
case 'c':
outb=smprint("%s%s", outb, format_t("%a %b %e %T %Y", t));
break;
case 'C':
outb=smprint("%s%.2d", outb, (t.year+1900)/100);
break;
case 'd':
outb=smprint("%s%.2d", outb, t.mday);
break;
case 'D':
outb=smprint("%s%s", outb, format_t("%m/%d/%y", t));
break;
case 'e':
outb=smprint("%s%2.d", outb, t.mday);
break;
case 'F':
outb=smprint("%s%s", outb, format_t("%Y-%m-%d", t));
break;
case 'h':
outb=smprint("%s%s", outb, format_t("%b", t));
break;
case 'H':
outb=smprint("%s%.2d", outb, t.hour);
break;
case 'I':
outb=smprint("%s%.2d", outb, t.hour%12);
break;
case 'j':
outb=smprint("%s%d", outb, t.yday);
break;
case 'k':
outb=smprint("%s%2.d", outb, t.hour);
break;
case 'l':
outb=smprint("%s%2.d", outb, t.hour%12);
break;
case 'm':
outb=smprint("%s%.2d", outb, t.mon+1);
break;
case 'M':
outb=smprint("%s%.2d", outb, t.min);
break;
case 'p':
if(t.hour < 12)
outb=smprint("%s%s", outb, "AM");
else
outb=smprint("%s%s", outb, "PM");
break;
case 'r':
outb=smprint("%s%s", outb, format_t("%I:%M:%S %p", t));
break;
case 'R':
outb=smprint("%s%s", outb, format_t("%H:%M", t));
break;
case 's':
outb=smprint("%s%ld", outb, now);
break;
case 'S':
outb=smprint("%s%.2d", outb, t.sec);
break;
case 'T':
outb=smprint("%s%s", outb, format_t("%H:%M:%S", t));
break;
case 'u':
if(t.wday==0)
outb=smprint("%s%d", outb, 7);
else
outb=smprint("%s%d", outb, t.wday);
break;
case 'v':
outb=smprint("%s%s", outb, format_t("%e-%b-%Y", t));
break;
case 'x':
outb=smprint("%s%s", outb, format_t("%m/%d/%y", t));
break;
case 'X':
outb=smprint("%s%s", outb, format_t("%T", t));
break;
case 'y':
outb=smprint("%s%.2d", outb, t.year%100);
break;
case 'Y':
outb=smprint("%s%.4d", outb, t.year+1900);
break;
case 'w':
outb=smprint("%s%d", outb, t.wday);
break;
case 'z':
outb=smprint("%s%+.2d:%u.2d", outb, t.tzoff/(60*60),
(t.tzoff%(60*60))/60);
break;
case 'Z':
outb=smprint("%s%s", outb, t.zone);
break;
case '+':
outb=smprint("%s%s", outb, ctime(now));
break;
/* Made-up additions */
case ',': /* Truncated Julian Day (TJD) */
outb=smprint("%s%d", outb,
(int)(2440587.5 + (now/(60*60*24)) - 2440000.5));
break;
case '.': /* TJD w/ fractional days */
outb=smprint("%s%f", outb,
(2440587.5 + (now/(60*60*24.0)) - 2440000.5));
break;
/* Literals and others */
case ' ':
outb=smprint("%s%s", outb, "% ");
break;
case '%':
outb=smprint("%s%s", outb, "%");
break;
case 'n':
outb=smprint("%s%s", outb, "\n");
break;
case 't':
outb=smprint("%s%s", outb, " ");
break;
default:
break;
}
}
return outb;
}
|