strftime.c (3852B)
1 #include <stdio.h> 2 #include <time.h> 3 #include <string.h> 4 5 static char *weekday[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; 6 static char *wday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; 7 static char *month[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", 8 "October", "November", "December" }; 9 static char *mon[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; 10 11 12 size_t strftime(char *buf, size_t maxsize, const char *fmt, const struct tm *tm) 13 { 14 char *ep = buf + maxsize - 1; 15 char *p = buf; 16 int c; 17 char tmp[40]; 18 19 while (*fmt) { 20 if ((c = *fmt++) != '%') { 21 if (p >= ep) 22 return 0; 23 *p++ = c; 24 continue; 25 } 26 27 switch (c = *fmt++) { 28 case 0: 29 return 0; 30 31 default: 32 if (p+1 >= ep) 33 return 0; 34 *p++ = '%'; 35 *p++ = c; 36 break; 37 38 case 'A': 39 strcpy(tmp, weekday[tm->tm_wday]); 40 break; 41 case 'a': 42 strcpy(tmp, wday[tm->tm_wday]); 43 break; 44 case 'B': 45 strcpy(tmp, month[tm->tm_mon]); 46 break; 47 case 'h': 48 case 'b': 49 strcpy(tmp, mon[tm->tm_mon]); 50 break; 51 case 'C': 52 sprintf(tmp, "%02d", (tm->tm_year+1900)/100); 53 break; 54 case 'c': 55 sprintf(tmp, "%02d:%02d:%02d %02d/%02d/%04d", 56 tm->tm_hour, tm->tm_min, tm->tm_sec, 57 tm->tm_mon+1, tm->tm_mday, tm->tm_year+1900); 58 break; 59 case 'D': 60 strftime(tmp, sizeof tmp, "%m/%d/%y", tm); 61 break; 62 case 'd': 63 sprintf(tmp, "%02d", tm->tm_mday); 64 break; 65 case 'e': 66 sprintf(tmp, "%2d", tm->tm_mday); 67 break; 68 case 'F': 69 strftime(tmp, sizeof tmp, "%Y-%m-%d", tm); 70 break; 71 case 'G': 72 // Not quite right - sometimes the previous or next year! 73 sprintf(tmp, "%04d", tm->tm_year + 1900); 74 break; 75 case 'g': 76 strftime(tmp, sizeof tmp, "%G", tm); 77 memmove(tmp, tmp+2, strlen(tmp+2)+1); 78 break; 79 case 'H': 80 sprintf(tmp, "%02d", tm->tm_hour); 81 break; 82 case 'I': 83 sprintf(tmp, "%02d", (tm->tm_hour+11) % 12 + 1); 84 break; 85 case 'j': 86 sprintf(tmp, "%03d", tm->tm_yday + 1); 87 break; 88 case 'k': 89 sprintf(tmp, "%2d", tm->tm_hour); 90 break; 91 case 'l': 92 sprintf(tmp, "%2d", (tm->tm_hour+11) % 12 + 1); 93 break; 94 case 'M': 95 sprintf(tmp, "%02d", tm->tm_min); 96 break; 97 case 'm': 98 sprintf(tmp, "%02d", tm->tm_mon+1); 99 break; 100 case 'n': 101 strcpy(tmp, "\n"); 102 break; 103 case 'p': 104 if (tm->tm_hour < 12) 105 strcpy(tmp, "am"); 106 else 107 strcpy(tmp, "pm"); 108 break; 109 case 'R': 110 strftime(tmp, sizeof tmp, "%H:%M", tm); 111 break; 112 case 'r': 113 strftime(tmp, sizeof tmp, "%I:%M:%S %p", tm); 114 break; 115 case 'S': 116 sprintf(tmp, "%02d", tm->tm_sec); 117 break; 118 case 's': 119 sprintf(tmp, "%d", (int)mktime(tm)); 120 break; 121 case 'T': 122 strftime(tmp, sizeof tmp, "%H:%M:%S", tm); 123 break; 124 case 't': 125 strcpy(tmp, "\t"); 126 break; 127 case 'U': 128 sprintf(tmp, "%02d", tm->tm_yday/7); // not quite right 129 break; 130 case 'u': 131 sprintf(tmp, "%d", tm->tm_wday ? tm->tm_wday : 7); 132 break; 133 case 'V': 134 sprintf(tmp, "%02d", 1 + tm->tm_yday/7); // not quite right 135 break; 136 case 'v': 137 strftime(tmp, sizeof tmp, "%e-%b-%Y", tm); 138 break; 139 case 'W': 140 sprintf(tmp, "%02d", tm->tm_yday/7); // not quite right 141 break; 142 case 'w': 143 sprintf(tmp, "%d", tm->tm_wday); 144 break; 145 case 'X': 146 sprintf(tmp, "%02d:%02d:%02d", 147 tm->tm_hour, tm->tm_min, tm->tm_sec); 148 break; 149 case 'x': 150 sprintf(tmp, "%%02d/%02d/%04d", 151 tm->tm_mon+1, tm->tm_mday, tm->tm_year+1900); 152 break; 153 case 'Y': 154 sprintf(tmp, "%d", tm->tm_year+1900); 155 break; 156 case 'y': 157 sprintf(tmp, "%02d", tm->tm_year%100); 158 break; 159 case 'Z': 160 strcpy(tmp, "GMT"); 161 break; 162 case 'z': 163 strcpy(tmp, "+0000"); 164 break; 165 case '%': 166 strcpy(tmp, "%"); 167 break; 168 } 169 if(p+strlen(tmp) > ep) 170 return 0; 171 strcpy(p, tmp); 172 p += strlen(p); 173 } 174 *p = 0; 175 return p - buf; 176 } 177