strftime.c
来自「国外网站上的一些精典的C程序」· C语言 代码 · 共 336 行
C
336 行
/** * * strftime.c * * implements the ansi c function strftime() * * written 6 september 1989 by jim nutt * released into the public domain by jim nutt * * modified 21-Oct-89 by Rob Duff ***/#include <stddef.h> /* for size_t */#include <stdarg.h> /* for va_arg */#include <time.h> /* for struct tm */#include "strftime.h"static char *aday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};static char *day[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};static char *amonth[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};static char *month[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};char *tzname_[2] = {"CST", "CDT"}; /* Add your own defaults here */static char buf[26];static void strfmt(char *str, const char *fmt, ...);/** * * size_t strftime_(char *str, * size_t maxs, * const char *fmt, * const struct tm *t) * * this functions acts much like a sprintf for time/date output. * given a pointer to an output buffer, a format string and a * time, it copies the time to the output buffer formatted in * accordance with the format string. the parameters are used * as follows: * * str is a pointer to the output buffer, there should * be at least maxs characters available at the address * pointed to by str. * * maxs is the maximum number of characters to be copied * into the output buffer, included the '\0' terminator * * fmt is the format string. a percent sign (%) is used * to indicate that the following character is a special * format character. the following are valid format * characters: * * %A full weekday name (Monday) * %a abbreviated weekday name (Mon) * %B full month name (January) * %b abbreviated month name (Jan) * %c standard date and time representation * %d day-of-month (01-31) * %H hour (24 hour clock) (00-23) * %I hour (12 hour clock) (01-12) * %j day-of-year (001-366) * %M minute (00-59) * %m month (01-12) * %p local equivalent of AM or PM * %S second (00-59) * %U week-of-year, first day sunday (00-53) * %W week-of-year, first day monday (00-53) * %w weekday (0-6, sunday is 0) * %X standard time representation * %x standard date representation * %Y year with century * %y year without century (00-99) * %Z timezone name * %% percent sign * * the standard date string is equivalent to: * * %a %b %d %Y * * the standard time string is equivalent to: * * %H:%M:%S * * the standard date and time string is equivalent to: * * %a %b %d %H:%M:%S %Y * * strftime_() returns the number of characters placed in the * buffer, not including the terminating \0, or zero if more * than maxs characters were produced. ***/size_t strftime_(char *s, size_t maxs, const char *f, const struct tm *t){ int w; char *p, *q, *r; p = s; q = s + maxs - 1; while ((*f != '\0')) { if (*f++ == '%') { r = buf; switch (*f++) { case '%' : r = "%"; break; case 'a' : r = aday[t->tm_wday]; break; case 'A' : r = day[t->tm_wday]; break; case 'b' : r = amonth[t->tm_mon]; break; case 'B' : r = month[t->tm_mon]; break; case 'c' : strfmt(r, "%0 %0 %2 %2:%2:%2 %4", aday[t->tm_wday], amonth[t->tm_mon], t->tm_mday,t->tm_hour, t->tm_min, t->tm_sec, t->tm_year+1900); break; case 'd' : strfmt(r,"%2",t->tm_mday); break; case 'H' : strfmt(r,"%2",t->tm_hour); break; case 'I' : strfmt(r,"%2",(t->tm_hour%12)?t->tm_hour%12:12); break; case 'j' : strfmt(r,"%3",t->tm_yday+1); break; case 'm' : strfmt(r,"%2",t->tm_mon+1); break; case 'M' : strfmt(r,"%2",t->tm_min); break; case 'p' : r = (t->tm_hour>11)?"PM":"AM"; break; case 'S' : strfmt(r,"%2",t->tm_sec); break; case 'U' : w = t->tm_yday/7; if (t->tm_yday%7 > t->tm_wday) w++; strfmt(r, "%2", w); break; case 'W' : w = t->tm_yday/7; if (t->tm_yday%7 > (t->tm_wday+6)%7) w++; strfmt(r, "%2", w); break; case 'w' : strfmt(r,"%1",t->tm_wday); break; case 'x' : strfmt(r, "%3s %3s %2 %4", aday[t->tm_wday], amonth[t->tm_mon], t->tm_mday, t->tm_year+1900); break; case 'X' : strfmt(r, "%2:%2:%2", t->tm_hour, t->tm_min, t->tm_sec); break; case 'y' : strfmt(r,"%2",t->tm_year%100); break; case 'Y' : strfmt(r,"%4",t->tm_year+1900); break; case 'Z' : r = (t->tm_isdst && tzname_[1][0]) ? tzname_[1] : tzname_[0]; break; default: buf[0] = '%'; /* reconstruct the format */ buf[1] = f[-1]; buf[2] = '\0'; if (buf[1] == 0) f--; /* back up if at end of string */ } while (*r) { if (p == q) { *q = '\0'; return 0; } *p++ = *r++; } } else { if (p == q) { *q = '\0'; return 0; } *p++ = f[-1]; } } *p = '\0'; return p - s;}/* * stdarg.h *typedef void *va_list;#define va_start(vp,v) (vp=((char*)&v)+sizeof(v))#define va_arg(vp,t) (*((t*)(vp))++)#define va_end(vp) * */static int pow[5] = { 1, 10, 100, 1000, 10000 };/** * static void strfmt(char *str, char *fmt); * * simple sprintf for strftime * * each format descriptor is of the form %n * where n goes from zero to four * * 0 -- string %s * 1..4 -- int %?.?d ***/static void strfmt(char *str, const char *fmt, ...){ int ival, ilen; char *sval; va_list vp; va_start(vp, fmt); while (*fmt) { if (*fmt++ == '%') { ilen = *fmt++ - '0'; if (ilen == 0) /* zero means string arg */ { sval = va_arg(vp, char*); while (*sval) *str++ = *sval++; } else /* always leading zeros */ { ival = va_arg(vp, int); while (ilen) { ival %= pow[ilen--]; *str++ = (char)('0' + ival / pow[ilen]); } } } else *str++ = fmt[-1]; } *str = '\0'; va_end(vp);}#ifdef TEST#include <stdio.h> /* for printf */#include <time.h> /* for strftime */char test[80];int main(int argc, char *argv[]){ int len; char *fmt; time_t now; time(&now); fmt = (argc == 1) ? "%I:%M %p\n%c\n" : argv[1]; len = strftime(test,sizeof test, fmt, localtime(&now)); printf("%d: %s\n", len, test); return !len;}#endif /* TEST */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?