#include #include 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; }