|
|
1.1 root 1: /*
2: * libc/gen/strftime.c
3: * C standard date and time library.
4: * strftime()
5: * ANSI 4.12.3.5.
6: * "C" locale-specific time and date formatting,
7: * with the locale-dependent stuff wired in here.
8: * Special thanks to the ANSI committee for this marvelous idea.
9: */
10:
11: #include <stddef.h>
12: #include <string.h>
13: #include <time.h>
14:
15: /* Forward. */
16: static char *toasc();
17: static char *convert();
18:
19: /* Static data. */
20: static const char *weekdays[] = {
21: "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
22: };
23: static const char *months[] = {
24: "January", "February", "March", "April", "May", "June",
25: "July", "August", "September", "October", "November", "December"
26: };
27:
28: size_t
29: strftime(s, maxsize, format, timeptr)
30: char *s;
31: size_t maxsize;
32: const char *format;
33: const struct tm *timeptr;
34: {
35: register size_t nchars, i;
36: register int j;
37: register char *x;
38: char c;
39:
40: for (nchars = 0; ; ) {
41: if ((c = *format++) != '%') {
42: if (++nchars > maxsize)
43: return 0;
44: *s++ = c;
45: if (c == '\0')
46: return --nchars;
47: } else {
48:
49: /* Perform a conversion. */
50: x = NULL;
51: switch (c = *format++) {
52:
53: case 'a':
54: case 'A':
55: x = weekdays[timeptr->tm_wday];
56: i = (c == 'a') ? 3 : strlen(x);
57: break;
58:
59: case 'b':
60: case 'B':
61: x = months[timeptr->tm_mon];
62: i = (c == 'b') ? 3 : strlen(x);
63: break;
64:
65: case 'c':
66: x = asctime(timeptr);
67: i = 24; /* suppress the '\n' */
68: break;
69:
70: case 'd':
71: j = timeptr->tm_mday;
72: i = 2;
73: break;
74:
75: case 'H':
76: j = timeptr->tm_hour;
77: i = 2;
78: break;
79:
80: case 'I':
81: if ((j = timeptr->tm_hour % 12) == 0)
82: j = 12;
83: i = 2;
84: break;
85:
86: case 'j':
87: j = timeptr->tm_yday + 1;
88: i = 3;
89: break;
90:
91: case 'm':
92: j = timeptr->tm_mon + 1;
93: i = 2;
94: break;
95:
96: case 'M':
97: j = timeptr->tm_min;
98: i = 2;
99: break;
100:
101: case 'p':
102: x = (timeptr->tm_hour) < 12 ? "AM" : "PM";
103: i = 2;
104: break;
105:
106: case 'S':
107: j = timeptr->tm_sec;
108: i = 2;
109: break;
110:
111: case 'U':
112: j = (timeptr->tm_yday + 7 - timeptr->tm_wday) / 7;
113: i = 2;
114: break;
115:
116: case 'w':
117: j = (timeptr->tm_yday + 8 - timeptr->tm_wday) / 7;
118: if (timeptr->tm_wday == 0)
119: --j;
120: i = 2;
121: break;
122:
123: case 'W':
124: j = timeptr->tm_wday;
125: i = 1;
126: break;
127:
128: case 'x':
129: x = convert(timeptr->tm_mon+1,
130: timeptr->tm_mday,
131: timeptr->tm_year,
132: '/');
133: i = 8;
134: break;
135:
136: case 'X':
137: x = convert(timeptr->tm_hour,
138: timeptr->tm_min,
139: timeptr->tm_sec,
140: ':');
141: i = 8;
142: break;
143:
144: case 'y':
145: j = timeptr->tm_year;
146: i = 2;
147: break;
148:
149: case 'Y':
150: j = timeptr->tm_year + 1900;
151: i = 4;
152: break;
153:
154: case 'z':
155: x = &tzname[(timeptr->tm_isdst==1) ? 1 :0][0];
156: i = strlen(x);
157: break;
158:
159: /* Default case has undefined behavior. */
160: /* This copies the given character, e.g. "%e" copies "e". */
161: case '%':
162: default:
163: x = &c;
164: i = 1;
165: break;
166: }
167:
168: /* Convert j to i ASCII digits if necessary. */
169: if (x == NULL)
170: x = toasc(j, i);
171:
172: /* Copy i characters from x to the result string. */
173: /* If nchars+i == maxsize, there will be no room for NUL. */
174: if ((nchars += i) >= maxsize)
175: return 0;
176: strncpy(s, x, i);
177: s += i;
178: }
179: }
180: }
181:
182: /*
183: * Convert i to n ASCII decimal digits.
184: */
185: static
186: char *
187: toasc(i, n) register unsigned int i, n;
188: {
189: static char *buf[6];
190: char *cp;
191:
192: cp = &buf[5];
193: *cp = '\0';
194: while (n--) {
195: *--cp = '0' + (i % 10);
196: i /= 10;
197: }
198: return cp;
199: }
200:
201: /*
202: * Convert a time or date to "hh:mm:ss" or "mm/dd/yy".
203: * The result is not NUL-terminated.
204: */
205: static
206: char *
207: convert(i1, i2, i3, sep) int i1, i2, i3, sep;
208: {
209: static char buf[8];
210: register char *s;
211:
212: s = &buf[0];
213: *s++ = '0' + i1 / 10;
214: *s++ = '0' + i1 % 10;
215: *s++ = sep;
216: *s++ = '0' + i2 / 10;
217: *s++ = '0' + i2 % 10;
218: *s++ = sep;
219: *s++ = '0' + i3 / 10;
220: *s++ = '0' + i3 % 10;
221: return buf;
222: }
223:
224: /* end of libc/gen/strftime.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.