char * conv_date_pict ( long date, const char *picture) { static char *month_name [] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, *day_name [] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }, formatted [FORMAT_MAX + 1]; /* Formatted return string */ int century, /* Century component of date */ year, /* Year component of date */ month, /* Month component of date */ day, /* Day component of date */ cursize; /* Size of current component */ char *dest, /* Store formatted data here */ ch, /* Next character in picture */ lastch = '0'; /* Last character we output */ long full_date = date; conv_reason = 0; /* No conversion errors so far */ /* Zero date is returned as empty string */ if (date == 0) { strclr (formatted); return (formatted); } default_century (&full_date); century = GET_CENTURY (full_date); year = GET_YEAR (full_date); month = GET_MONTH (full_date); day = GET_DAY (full_date); ASSERT (month > 0 && month <= 12); ASSERT (day > 0 && day <= 31); /* Scan through picture, converting each component */ dest = formatted; *dest = 0; /* string is empty */ while (*picture) { /* Get character and count number of occurences */ ch = *picture++; for (cursize = 1; *picture == ch; cursize++) picture++; switch (ch) { /* cc century 2 digits, 01-99 */ case 'c': if (cursize == 2) sprintf (dest, "%02d", century); break; /* y day of year, 1-366 */ /* yy year 2 digits, 00-99 */ /* yyyy year 4 digits, 0100-9999 */ case 'y': /* y = day of year */ if (cursize == 1) sprintf (dest, "%d", julian_date (full_date)); else if (cursize == 2) sprintf (dest, "%02d", year); else if (cursize == 4) sprintf (dest, "%02d%02d", century, year); break; /* m month, 1-12 */ /* mm month, 01-12 */ /* mmm month, 3 letters */ /* mmmm month, full name */ case 'm': if (cursize == 1) sprintf (dest, (isdigit (lastch)? "%2d": "%d"), month); else if (cursize == 2) sprintf (dest, "%02d", month); else if (cursize == 3) { memcpy (dest, month_name [month - 1], 3); dest [3] = 0; } else if (cursize == 4) strcpy (dest, month_name [month - 1]); break; /* MMM month, 3-letters, ucase */ /* MMMM month, full name, ucase */ case 'M': if (cursize == 3) { memcpy (dest, month_name [month - 1], 3); dest [3] = 0; strupc (dest); } else if (cursize == 4) { strcpy (dest, month_name [month - 1]); strupc (dest); } break; /* d day, 1-31 */ /* dd day, 01-31 */ /* ddd day of week, Sun-Sat */ /* dddd day of week, Sunday-Saturday */ case 'd': if (cursize == 1) sprintf (dest, (isdigit (lastch)? "%2d": "%d"), day); else if (cursize == 2) sprintf (dest, "%02d", day); else if (cursize == 3) { memcpy (dest, day_name [day_of_week (full_date)], 3); dest [3] = 0; } else if (cursize == 4) strcpy (dest, day_name [day_of_week (full_date)]); break; /* DDD day of week, SUN-SAT */ /* DDDD day of week, SUNDAY-SATURDAY */ case 'D': if (cursize == 3) { memcpy (dest, day_name [day_of_week (full_date)], 3); dest [3] = 0; strupc (dest); } else if (cursize == 4) { strcpy (dest, day_name [day_of_week (full_date)]); strupc (dest); } break; /* w day of week, 1-7 (1=Sunday) */ /* ww week of year, 1-53 */ case 'w': if (cursize == 1) sprintf (dest, "%d", day_of_week (full_date) + 1); else if (cursize == 2) sprintf (dest, "%d", week_of_year (full_date)); break; /* q year quarter, 1-4 */ case 'q': if (cursize == 1) sprintf (dest, "%d", year_quarter (full_date)); break; /* \x literal character x */ case '\\': ch = *picture++; } if (*dest) /* If something was output, */ while (*dest) /* skip to end of string */ dest++; else while (cursize--) /* Else output ch once or more */ *dest++ = ch; /* and bump dest pointer */ lastch = *(dest - 1); /* Get previous character */ *dest = 0; /* Terminate the string nicely */ } return (formatted); }
size_t strftime(char *buffer, size_t limit, const char *pattern, const struct tm * timeptr) { unsigned int count, length; int d, w; char c; char _store[26]; struct week_date wd; count = length = 0; while (count < limit) { c = *pattern++; if (c == '%') { c = *pattern++; if (c == 'E' || c == 'O') c = *pattern++; switch (c) { case ('%'): _store[0] = c; length = 1; break; case ('a'): length = pgm_copystring(strfwkdays, timeptr->tm_wday, _store, 3); break; case ('A'): length = pgm_copystring(strfwkdays, timeptr->tm_wday, _store, 255); break; case ('b'): case ('h'): length = pgm_copystring(strfmonths, timeptr->tm_mon, _store, 3); break; case ('B'): length = pgm_copystring(strfmonths, timeptr->tm_mon, _store, 255); break; case ('c'): asctime_r(timeptr, _store); length = 0; while (_store[length]) length++; break; case ('C'): d = timeptr->tm_year + 1900; d /= 100; length = sprintf(_store, "%.2d", d); break; case ('d'): length = sprintf(_store, "%.2u", timeptr->tm_mday); break; case ('D'): length = sprintf(_store, "%.2u/%.2u/%.2u", \ timeptr->tm_mon + 1, \ timeptr->tm_mday, \ timeptr->tm_year % 100 \ ); break; case ('e'): length = sprintf(_store, "%2d", timeptr->tm_mday); break; case ('F'): length = sprintf(_store, "%d-%.2d-%.2d", \ timeptr->tm_year + 1900, \ timeptr->tm_mon + 1, \ timeptr->tm_mday \ ); break; case ('g'): case ('G'): iso_week_date_r(timeptr->tm_year + 1900, timeptr->tm_yday, &wd); if (c == 'g') { length = sprintf(_store, "%.2d", wd.year % 100); } else { length = sprintf(_store, "%.4d", wd.year); } break; case ('H'): length = sprintf(_store, "%.2u", timeptr->tm_hour); break; case ('I'): d = timeptr->tm_hour % 12; if (d == 0) d = 12; length = sprintf(_store, "%.2u", d); break; case ('j'): length = sprintf(_store, "%.3u", timeptr->tm_yday + 1); break; case ('m'): length = sprintf(_store, "%.2u", timeptr->tm_mon + 1); break; case ('M'): length = sprintf(_store, "%.2u", timeptr->tm_min); break; case ('n'): _store[0] = 10; length = 1; break; case ('p'): length = 2; _store[0] = 'A'; if (timeptr->tm_hour > 11) _store[0] = 'P'; _store[1] = 'M'; _store[2] = 0; break; case ('r'): d = timeptr->tm_hour % 12; if (d == 0) d = 12; length = sprintf(_store, "%2d:%.2d:%.2d AM", \ d, \ timeptr->tm_min, \ timeptr->tm_sec \ ); if (timeptr->tm_hour > 11) _store[10] = 'P'; break; case ('R'): length = sprintf(_store, "%.2d:%.2d", timeptr->tm_hour, timeptr->tm_min); break; case ('S'): length = sprintf(_store, "%.2u", timeptr->tm_sec); break; case ('t'): length = sprintf(_store, "\t"); break; case ('T'): length = sprintf(_store, "%.2d:%.2d:%.2d", \ timeptr->tm_hour, \ timeptr->tm_min, \ timeptr->tm_sec \ ); break; case ('u'): w = timeptr->tm_wday; if (w == 0) w = 7; length = sprintf(_store, "%d", w); break; case ('U'): length = sprintf(_store, "%.2u", week_of_year(timeptr, 0)); break; case ('V'): iso_week_date_r(timeptr->tm_year + 1900, timeptr->tm_yday, &wd); length = sprintf(_store, "%.2u", wd.week); break; case ('w'): length = sprintf(_store, "%u", timeptr->tm_wday); break; case ('W'): w = week_of_year(timeptr, 1); length = sprintf(_store, "%.2u", w); break; case ('x'): length = sprintf(_store, "%.2u/%.2u/%.2u", timeptr->tm_mon + 1, timeptr->tm_mday, timeptr->tm_year % 100); break; case ('X'): length = sprintf(_store, "%.2u:%.2u:%.2u", timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); break; case ('y'): length = sprintf(_store, "%.2u", timeptr->tm_year % 100); break; case ('Y'): length = sprintf(_store, "%u", timeptr->tm_year + 1900); break; case ('z'): d = __utc_offset / 60; w = timeptr->tm_isdst / 60; if (w > 0) d += w; w = abs(d % 60); d = d / 60; length = sprintf(_store, "%+.2d%.2d", d, w); break; default: length = 1; _store[0] = '?'; _store[1] = 0; break; } if ((length + count) < limit) { count += length; for (d = 0; d < (int) length; d++) { *buffer++ = _store[d]; } } else { *buffer = 0; return count; } } else { /* copy a literal */ *buffer = c; buffer++; count++; if (c == 0) return count; } } *buffer = 0; return count; }