]>
git.zerfleddert.de Git - micropolis/blob - src/tclx/ossupp/strftime.c
f46dfd7e8cdc11f9120cb56495bf78b00ec5c89a
4 * Public-domain relatively quick-and-dirty implemenation of
5 * ANSI library routine for System V Unix systems.
7 * It's written in old-style C for maximal portability.
9 * The code for %c, %x, and %X is my best guess as to what's "appropriate".
10 * This version ignores LOCALE information.
11 * It also doesn't worry about multi-byte characters.
15 * January, February, 1991
17 * Fixes from ado@elsie.nci.nih.gov
19 *-----------------------------------------------------------------------------
20 * $Id: strftime.c,v 2.0 1992/10/16 04:52:16 markd Rel $
21 *-----------------------------------------------------------------------------
25 * To avoid Unix version problems, this code has been simplified to avoid
26 * const and size_t, however this can cause an incompatible definition on
27 * ansi-C systems, so a game is played with defines to ignore a strftime
28 * declaration in time.h
31 #define strftime ___srtftime
36 #include <sys/types.h>
40 extern char *strchr();
41 static int weeknumber();
43 #ifndef TCL_HAS_TM_ZONE
44 extern char *tzname
[2];
48 /* strftime --- produce formatted time */
51 strftime(s
, maxsize
, format
, timeptr
)
57 char *endp
= s
+ maxsize
;
62 /* various tables, useful in North America */
63 static char *days_a
[] = {
64 "Sun", "Mon", "Tue", "Wed",
67 static char *days_l
[] = {
68 "Sunday", "Monday", "Tuesday", "Wednesday",
69 "Thursday", "Friday", "Saturday",
71 static char *months_a
[] = {
72 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
73 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
75 static char *months_l
[] = {
76 "January", "February", "March", "April",
77 "May", "June", "July", "August", "September",
78 "October", "November", "December",
80 static char *ampm
[] = { "AM", "PM", };
82 if (s
== NULL
|| format
== NULL
|| timeptr
== NULL
|| maxsize
== 0)
85 if (strchr(format
, '%') == NULL
&& strlen(format
) + 1 >= maxsize
)
88 for (; *format
&& s
< endp
- 1; format
++) {
103 case 'a': /* abbreviated weekday name */
104 if (timeptr
->tm_wday
< 0 || timeptr
->tm_wday
> 6)
107 strcpy(tbuf
, days_a
[timeptr
->tm_wday
]);
110 case 'A': /* full weekday name */
111 if (timeptr
->tm_wday
< 0 || timeptr
->tm_wday
> 6)
114 strcpy(tbuf
, days_l
[timeptr
->tm_wday
]);
117 case 'h': /* abbreviated month name */
118 case 'b': /* abbreviated month name */
119 if (timeptr
->tm_mon
< 0 || timeptr
->tm_mon
> 11)
122 strcpy(tbuf
, months_a
[timeptr
->tm_mon
]);
125 case 'B': /* full month name */
126 if (timeptr
->tm_mon
< 0 || timeptr
->tm_mon
> 11)
129 strcpy(tbuf
, months_l
[timeptr
->tm_mon
]);
132 case 'c': /* appropriate date and time representation */
133 sprintf(tbuf
, "%s %s %2d %02d:%02d:%02d %d",
134 days_a
[timeptr
->tm_wday
],
135 months_a
[timeptr
->tm_mon
],
140 timeptr
->tm_year
+ 1900);
143 case 'd': /* day of the month, 01 - 31 */
144 sprintf(tbuf
, "%02d", timeptr
->tm_mday
);
147 case 'H': /* hour, 24-hour clock, 00 - 23 */
148 sprintf(tbuf
, "%02d", timeptr
->tm_hour
);
151 case 'I': /* hour, 12-hour clock, 01 - 12 */
152 i
= timeptr
->tm_hour
;
157 sprintf(tbuf
, "%02d", i
);
160 case 'j': /* day of the year, 001 - 366 */
161 sprintf(tbuf
, "%03d", timeptr
->tm_yday
+ 1);
164 case 'm': /* month, 01 - 12 */
165 sprintf(tbuf
, "%02d", timeptr
->tm_mon
+ 1);
168 case 'M': /* minute, 00 - 59 */
169 sprintf(tbuf
, "%02d", timeptr
->tm_min
);
172 case 'p': /* am or pm based on 12-hour clock */
173 if (timeptr
->tm_hour
< 12)
174 strcpy(tbuf
, ampm
[0]);
176 strcpy(tbuf
, ampm
[1]);
179 case 'S': /* second, 00 - 61 */
180 sprintf(tbuf
, "%02d", timeptr
->tm_sec
);
183 case 'U': /* week of year, Sunday is first day of week */
184 sprintf(tbuf
, "%d", weeknumber(timeptr
, 0));
187 case 'w': /* weekday, Sunday == 0, 0 - 6 */
188 sprintf(tbuf
, "%d", timeptr
->tm_wday
);
191 case 'W': /* week of year, Monday is first day of week */
192 sprintf(tbuf
, "%d", weeknumber(timeptr
, 1));
195 case 'x': /* appropriate date representation */
196 sprintf(tbuf
, "%s %s %2d %d",
197 days_a
[timeptr
->tm_wday
],
198 months_a
[timeptr
->tm_mon
],
200 timeptr
->tm_year
+ 1900);
203 case 'X': /* appropriate time representation */
204 sprintf(tbuf
, "%02d:%02d:%02d",
210 case 'y': /* year without a century, 00 - 99 */
211 i
= timeptr
->tm_year
% 100;
212 sprintf(tbuf
, "%d", i
);
215 case 'Y': /* year with century */
216 sprintf(tbuf
, "%d", 1900 + timeptr
->tm_year
);
219 case 'Z': /* time zone name or abbrevation */
220 #ifdef TCL_HAS_TM_ZONE
221 strcpy(tbuf
, timeptr
->tm_zone
);
224 if (daylight
&& timeptr
->tm_isdst
)
226 strcpy(tbuf
, tzname
[i
]);
230 case 'n': /* same as \n */
235 case 't': /* same as \t */
240 case 'D': /* date as %m/%d/%y */
241 strftime(tbuf
, sizeof tbuf
, "%m/%d/%y", timeptr
);
244 case 'e': /* day of month, blank padded */
245 sprintf(tbuf
, "%2d", timeptr
->tm_mday
);
248 case 'r': /* time as %I:%M:%S %p */
249 strftime(tbuf
, sizeof tbuf
, "%I:%M:%S %p", timeptr
);
252 case 'R': /* time as %H:%M */
253 strftime(tbuf
, sizeof tbuf
, "%H:%M", timeptr
);
256 case 'T': /* time as %H:%M:%S */
257 strftime(tbuf
, sizeof tbuf
, "%H:%M:%S", timeptr
);
268 if (s
+ i
< endp
- 1) {
275 if (s
< endp
&& *format
== '\0') {
282 /* weeknumber --- figure how many weeks into the year */
284 /* With thanks and tip of the hatlo to ado@elsie.nci.nih.gov */
287 weeknumber(timeptr
, firstweekday
)
291 if (firstweekday
== 0)
292 return (timeptr
->tm_yday
+ 7 - timeptr
->tm_wday
) / 7;
294 return (timeptr
->tm_yday
+ 7 -
295 (timeptr
->tm_wday
? (timeptr
->tm_wday
- 1) : 6)) / 7;