/*ident "@(#)Time:tm/tmform.c 3.1" */ /****************************************************************************** * * C++ Standard Components, Release 3.0. * * Copyright (c) 1991, 1992 AT&T and Unix System Laboratories, Inc. * Copyright (c) 1988, 1989, 1990 AT&T. All Rights Reserved. * * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T and Unix System * Laboratories, Inc. The copyright notice above does not evidence * any actual or intended publication of such source code. * ******************************************************************************/ #include #include #include "mytime.h" #define elements(x) (sizeof(x)/sizeof(x[0])) #define warped(t,n) ((t)<((n)-6L*30L*24L*60L*60L)||(t)>((n)+60L*60L)) static char* number(char*, long, int); /* * format date given clock * end of buf is returned */ char* tmform_ATTLC(char* buf, char* format, time_t* clock) { register char* cp; register char* p; register int n; int c; int i; int flags; struct tm* tp; char* stack[4]; char** sp; time_t now; tp = tmmake_ATTLC(clock); /* cout << "in tmform...\n" << " tp->tm_sec=" << tp->tm_sec << "\n" << " tp->tm_min=" << tp->tm_min << "\n" << " tp->tm_hour=" << tp->tm_hour << "\n" << " tp->tm_mday=" << tp->tm_mday << "\n" << " tp->tm_mon=" << tp->tm_mon << "\n" << " tp->tm_year=" << tp->tm_year << "\n" << " tp->tm_wday=" << tp->tm_wday << "\n" << " tp->tm_yday=" << tp->tm_yday << "\n" << " tp->tm_isdst=" << tp->tm_isdst << "\n" ; */ if (!format || !*format) format = tm_form_ATTLC[TM_DEFAULT]; flags = tm_flags_ATTLC; sp = &stack[0]; cp = buf; for (;;) { if (!(c = *format++)) { if (sp <= &stack[0]) break; format = *--sp; continue; } if (c != '%') { *cp++ = c; continue; } switch (*format++) { case 0: format--; continue; case '%': *cp++ = '%'; continue; case 'a': /* abbreviated day of week name */ n = TM_DAY_3 + tp->tm_wday; goto index; case 'A': /* day of week name */ n = TM_DAY + tp->tm_wday; goto index; case 'b': /* abbreviated month name */ case 'h': n = TM_MONTH_3 + tp->tm_mon; goto index; case 'B': /* month name */ n = TM_MONTH + tp->tm_mon; goto index; case 'c': /* `ctime(3)' date sans newline */ p = "%a %b %e %T %Y"; goto push; case 'C': /* `date(1)' date */ p = "%a %b %e %T %Z %Y"; goto push; case 'd': /* day of month */ cp = number(cp, (long)tp->tm_mday, 2); continue; case 'D': /* date */ p = "%m/%d/%y"; goto push; case 'E': /* no pad day of month */ cp = number(cp, (long)tp->tm_mday, 0); continue; case 'e': /* blank padded day of month */ cp = number(cp, (long)tp->tm_mday, -2); continue; case 'H': /* hour (0 - 23) */ cp = number(cp, (long)tp->tm_hour, 2); continue; case 'i': /* international `date(1)' date */ p = "%a %b %e %T %z %Z %Y"; goto push; case 'I': /* hour (0 - 12) */ if ((n = tp->tm_hour) > 12) n -= 12; else if (n == 0) n = 12; cp = number(cp, (long)n, 2); continue; case 'J': /* Julian date (0 offset) */ cp = number(cp, (long)tp->tm_yday, 3); continue; case 'j': /* Julian date (1 offset) */ cp = number(cp, (long)(tp->tm_yday + 1), 3); continue; case 'l': /* `ls -l' date */ p = "%b %e %H:%M"; if (clock) { (void)time(&now); if (warped(*clock, now)) p = "%b %e %Y"; } goto push; case 'm': /* month number */ cp = number(cp, (long)(tp->tm_mon + 1), 2); continue; case 'M': /* minutes */ cp = number(cp, (long)tp->tm_min, 2); continue; case 'n': *cp++ = '\n'; continue; case 'p': /* meridian */ n = TM_MERIDIAN + (tp->tm_hour >= 12); goto index; case 'r': p = "%I:%M:%S %p"; goto push; case 'R': p = "%H:%M"; goto push; case 'S': /* seconds */ cp = number(cp, (long)tp->tm_sec, 2); continue; case 't': *cp++ = '\t'; continue; case 'T': p = "%H:%M:%S"; goto push; case 'U': /* week number, Sunday as first day */ i = tp->tm_yday - tp->tm_wday; week: if (i >= -3 ) { n = (i + 1) / 7 + 1; if (i % 7 >= 4) n++; } else n = 52; cp = number(cp, (long)n, 2); continue; case 'w': /* weekday number */ cp = number(cp, (long)tp->tm_wday, 0); continue; case 'W': /* week number, Monday as first day */ if (tp->tm_wday == 0) i = tp->tm_yday - 6; else i = tp->tm_yday - tp->tm_wday + 1; goto week; case 'x': p = tm_form_ATTLC[TM_DATE]; goto push; case 'X': p = tm_form_ATTLC[TM_TIME]; goto push; case 'y': /* year in the form yy */ cp = number(cp, (long)(tp->tm_year % 100), 2); continue; case 'Y': /* year in the form ccyy */ cp = number(cp, (long)(1900 + tp->tm_year), 4); continue; case 'z': /* time zone type */ if (!(tm_flags_ATTLC & TM_UTC) && (p = tm_local_ATTLC->type)) goto string; continue; case 'Z': /* time zone */ p = ( (tm_flags_ATTLC & TM_UTC) ?( tm_form_ATTLC[TM_UT] ):( tp->tm_isdst ?( tm_local_ATTLC->daylight ):( tm_local_ATTLC->standard ) ) ); goto string; case '-': case '+': switch (*format++) { case 0: format--; continue; case 'l': n = TM_LEAP; break; case 'u': n = TM_UTC; break; } if (c == '+') { if (!(tm_flags_ATTLC & n)) { tm_flags_ATTLC |= n; tp = tmmake_ATTLC(clock); } } else if (tm_flags_ATTLC & n) { tm_flags_ATTLC &= ~n; tp = tmmake_ATTLC(clock); } continue; case '#': /* seconds since the epoch */ if (clock) now = *clock; else (void)time(&now); cp = number(cp, (long)now, 0); continue; default: *cp++ = c; *cp++ = *(format - 1); continue; } index: p = tm_form_ATTLC[n]; string: while (*cp = *p++) cp++; continue; push: if (sp < &stack[elements(stack)]) { *sp++ = format; format = p; } continue; } tm_flags_ATTLC = flags; *cp = 0; return(cp); } /* * format n with padding p into s * return end of s * * p: <0 blank padding * 0 no padding * >0 0 padding */ static char* number(register char* s, register long n, register int p) { if (p > 0) (void)sprintf(s, "%0*lu", p, n); else if (p < 0) (void)sprintf(s, "%*lu", -p, n); else (void)sprintf(s, "%lu", n); while (*s) s++; return(s); }