vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

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