Mercurial > hg > xemacs-beta
annotate src/strftime.c @ 5518:3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
2011-06-03 Aidan Kehoe <kehoea@parhasard.net>
* gnuslib.c (connect_to_unix_server):
Retry with /tmp as a directory in which to search for Unix sockets
if an attempt to connect with some other directory failed (which
may be because gnuclient and gnuserv don't share an environment
value for TMPDIR, or because gnuserv was compiled with USE_TMPDIR
turned off).
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Fri, 03 Jun 2011 18:40:57 +0100 |
parents | 308d34e9f07d |
children |
rev | line source |
---|---|
428 | 1 /* strftime - custom formatting of date and/or time |
2 Copyright (C) 1989, 1991, 1992 Free Software Foundation, Inc. | |
3 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5254
diff
changeset
|
4 This file is part of XEmacs. |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5254
diff
changeset
|
5 |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5254
diff
changeset
|
6 XEmacs is free software: you can redistribute it and/or modify it |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5254
diff
changeset
|
7 under the terms of the GNU General Public License as published by the |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5254
diff
changeset
|
8 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5254
diff
changeset
|
9 option) any later version. |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5254
diff
changeset
|
10 |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5254
diff
changeset
|
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5254
diff
changeset
|
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5254
diff
changeset
|
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5254
diff
changeset
|
14 for more details. |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5254
diff
changeset
|
15 |
428 | 16 You should have received a copy of the GNU General Public License |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5254
diff
changeset
|
17 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 18 /* Synched up with: FSF 19.30. */ |
19 | |
771 | 20 /* This file has been ... uhhhhh ... Mule-ized. Yeah. |
21 | |
22 (Everything here is external format. This is DANGEROUS and | |
23 data-lossy, but fixing it is too much of a bother now.) --ben */ | |
24 | |
428 | 25 /* Note: this version of strftime lacks locale support, |
26 but it is standalone. | |
27 | |
28 Performs `%' substitutions similar to those in printf. Except | |
29 where noted, substituted fields have a fixed size; numeric fields are | |
30 padded if necessary. Padding is with zeros by default; for fields | |
31 that display a single number, padding can be changed or inhibited by | |
32 following the `%' with one of the modifiers described below. Unknown | |
33 field specifiers are copied as normal characters. All other | |
34 characters are copied to the output without change. | |
35 | |
36 Supports a superset of the ANSI C field specifiers. | |
37 | |
38 Literal character fields: | |
39 % % | |
40 n newline | |
41 t tab | |
42 | |
43 Numeric modifiers (a nonstandard extension): | |
44 - do not pad the field | |
45 _ pad the field with spaces | |
46 | |
47 Time fields: | |
48 %H hour (00..23) | |
49 %I hour (01..12) | |
50 %k hour ( 0..23) | |
51 %l hour ( 1..12) | |
52 %M minute (00..59) | |
53 %p locale's AM or PM | |
54 %r time, 12-hour (hh:mm:ss [AP]M) | |
55 %R time, 24-hour (hh:mm) | |
56 %s time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension) | |
57 %S second (00..61) | |
58 %T time, 24-hour (hh:mm:ss) | |
59 %X locale's time representation (%H:%M:%S) | |
4203 | 60 %z time zone offset (e.g. +0530, -0800 etc) |
428 | 61 %Z time zone (EDT), or nothing if no time zone is determinable |
62 | |
63 Date fields: | |
64 %a locale's abbreviated weekday name (Sun..Sat) | |
65 %A locale's full weekday name, variable length (Sunday..Saturday) | |
66 %b locale's abbreviated month name (Jan..Dec) | |
67 %B locale's full month name, variable length (January..December) | |
68 %c locale's date and time (Sat Nov 04 12:02:33 EST 1989) | |
69 %C century (00..99) | |
70 %d day of month (01..31) | |
71 %e day of month ( 1..31) | |
72 %D date (mm/dd/yy) | |
4203 | 73 %G year corresponding to the ISO 8601 week |
74 %g Year of the ISO 8601 week within century (00 - 99) | |
428 | 75 %h same as %b |
76 %j day of year (001..366) | |
77 %m month (01..12) | |
78 %U week number of year with Sunday as first day of week (00..53) | |
4203 | 79 %V ISO 8601 week number (first week is the earliest one with Thu) |
428 | 80 %w day of week (0..6) |
81 %W week number of year with Monday as first day of week (00..53) | |
82 %x locale's date representation (mm/dd/yy) | |
83 %y last two digits of year (00..99) | |
84 %Y year (1970...) | |
85 | |
86 David MacKenzie <djm@gnu.ai.mit.edu> */ | |
87 | |
88 #ifdef HAVE_CONFIG_H | |
89 #include <config.h> | |
90 #include "lisp.h" | |
91 #endif | |
92 | |
93 #include <stdio.h> | |
94 #include <sys/types.h> | |
95 #if defined(TM_IN_SYS_TIME) || (!defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME)) | |
96 #include <sys/time.h> | |
97 #else | |
98 #include <time.h> | |
99 #endif | |
100 | |
101 #ifndef STDC_HEADERS | |
102 time_t mktime (); | |
103 #endif | |
104 | |
442 | 105 #if defined(WIN32_NATIVE) || defined(CYGWIN) |
428 | 106 #include <time.h> |
107 #else | |
108 #if defined(HAVE_TZNAME) | |
109 extern char *tzname[2]; | |
110 #endif | |
442 | 111 #endif /* WIN32_NATIVE */ |
428 | 112 |
113 #ifdef emacs | |
114 #define strftime emacs_strftime | |
115 #endif | |
116 | |
117 /* Types of padding for numbers in date and time. */ | |
118 enum padding | |
119 { | |
120 none, blank, zero | |
121 }; | |
122 | |
442 | 123 static char const* const days[] = |
428 | 124 { |
125 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" | |
126 }; | |
127 | |
442 | 128 static char const * const months[] = |
428 | 129 { |
130 "January", "February", "March", "April", "May", "June", | |
131 "July", "August", "September", "October", "November", "December" | |
132 }; | |
133 | |
5254
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
134 static char const * const roman_upper[] = |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
135 { |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
136 "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII" |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
137 }; |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
138 |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
139 static char const * const roman_lower[] = |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
140 { |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
141 "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix", "x", "xi", "xii" |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
142 }; |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
143 |
428 | 144 /* Add character C to STRING and increment LENGTH, |
145 unless LENGTH would exceed MAX. */ | |
146 | |
147 #define add_char(c) do \ | |
148 { \ | |
149 if (length + 1 <= max) \ | |
150 string[length++] = (c); \ | |
151 } while (0) | |
152 | |
153 /* Add a 2 digit number to STRING, padding if specified. | |
154 Return the number of characters added, up to MAX. */ | |
155 | |
156 static int | |
157 add_num2 (char *string, int num, int max, enum padding pad) | |
158 { | |
159 int top = num / 10; | |
160 int length = 0; | |
161 | |
162 if (top == 0 && pad == blank) | |
163 add_char (' '); | |
164 else if (top != 0 || pad == zero) | |
165 add_char (top + '0'); | |
166 add_char (num % 10 + '0'); | |
167 return length; | |
168 } | |
169 | |
170 /* Add a 3 digit number to STRING, padding if specified. | |
171 Return the number of characters added, up to MAX. */ | |
172 | |
173 static int | |
174 add_num3 (char *string, int num, int max, enum padding pad) | |
175 { | |
176 int top = num / 100; | |
177 int mid = (num - top * 100) / 10; | |
178 int length = 0; | |
179 | |
180 if (top == 0 && pad == blank) | |
181 add_char (' '); | |
182 else if (top != 0 || pad == zero) | |
183 add_char (top + '0'); | |
184 if (mid == 0 && top == 0 && pad == blank) | |
185 add_char (' '); | |
186 else if (mid != 0 || top != 0 || pad == zero) | |
187 add_char (mid + '0'); | |
188 add_char (num % 10 + '0'); | |
189 return length; | |
190 } | |
191 | |
192 /* Like strncpy except return the number of characters copied. */ | |
193 | |
194 static int | |
442 | 195 add_str (char *to, const char *from, int max) |
428 | 196 { |
197 int i; | |
198 | |
199 for (i = 0; from[i] && i <= max; ++i) | |
200 to[i] = from[i]; | |
201 return i; | |
202 } | |
203 | |
204 static int | |
205 add_num_time_t (char *string, int max, time_t num) | |
206 { | |
207 /* This buffer is large enough to hold the character representation | |
208 (including the trailing NUL) of any unsigned decimal quantity | |
209 whose binary representation fits in 128 bits. */ | |
210 char buf[40]; | |
211 | |
212 if (sizeof (num) > 16) | |
2500 | 213 ABORT (); |
428 | 214 sprintf (buf, "%lu", (unsigned long) num); |
793 | 215 return add_str (string, buf, max); |
428 | 216 } |
217 | |
218 /* Return the week in the year of the time in TM, with the weeks | |
219 starting on Sundays. */ | |
220 | |
221 static int | |
442 | 222 sun_week (const struct tm *tm) |
428 | 223 { |
224 int dl; | |
225 | |
226 /* Set `dl' to the day in the year of the last day of the week previous | |
227 to the one containing the day specified in TM. If the day specified | |
228 in TM is in the first week of the year, `dl' will be negative or 0. | |
229 Otherwise, calculate the number of complete weeks before our week | |
230 (dl / 7) and add any partial week at the start of the year (dl % 7). */ | |
231 dl = tm->tm_yday - tm->tm_wday; | |
232 return dl <= 0 ? 0 : dl / 7 + (dl % 7 != 0); | |
233 } | |
234 | |
235 /* Return the week in the year of the time in TM, with the weeks | |
236 starting on Mondays. */ | |
237 | |
238 static int | |
442 | 239 mon_week (const struct tm *tm) |
428 | 240 { |
241 int dl, wday; | |
242 | |
243 if (tm->tm_wday == 0) | |
244 wday = 6; | |
245 else | |
246 wday = tm->tm_wday - 1; | |
247 dl = tm->tm_yday - wday; | |
248 return dl <= 0 ? 0 : dl / 7 + (dl % 7 != 0); | |
249 } | |
250 | |
4203 | 251 #ifndef __isleap |
252 /* Nonzero if YEAR is a leap year (every 4 years, | |
253 except every 100th isn't, and every 400th is). */ | |
254 # define __isleap(year) \ | |
255 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) | |
256 #endif | |
257 | |
258 /* The number of days from the first day of the first ISO week of this | |
259 year to the year day YDAY with week day WDAY. ISO weeks start on | |
260 Monday; the first ISO week has the year's first Thursday. YDAY may | |
261 be as small as YDAY_MINIMUM. */ | |
262 #define ISO_WEEK_START_WDAY 1 /* Monday */ | |
263 #define ISO_WEEK1_WDAY 4 /* Thursday */ | |
264 #define YDAY_MINIMUM (-366) | |
265 static int | |
266 iso_week_days (int yday, int wday) | |
267 { | |
268 /* Add enough to the first operand of % to make it nonnegative. */ | |
269 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7; | |
270 return (yday | |
271 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7 | |
272 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY); | |
273 } | |
274 | |
428 | 275 #if !defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME) |
442 | 276 char *zone_name (const struct tm *tp); |
428 | 277 char * |
442 | 278 zone_name (const struct tm *tp) |
428 | 279 { |
280 char *timezone (); | |
281 struct timeval tv; | |
282 struct timezone tz; | |
283 | |
284 gettimeofday (&tv, &tz); | |
285 return timezone (tz.tz_minuteswest, tp->tm_isdst); | |
286 } | |
287 #endif | |
288 | |
289 /* Format the time given in TM according to FORMAT, and put the | |
290 results in STRING. | |
291 Return the number of characters (not including terminating null) | |
292 that were put into STRING, or 0 if the length would have | |
293 exceeded MAX. */ | |
294 | |
442 | 295 size_t strftime (char *string, size_t max, const char *format, |
296 const struct tm *tm); | |
428 | 297 |
298 size_t | |
442 | 299 strftime (char *string, size_t max, const char *format, const struct tm *tm) |
428 | 300 { |
301 enum padding pad; /* Type of padding to apply. */ | |
302 size_t length = 0; /* Characters put in STRING so far. */ | |
303 | |
304 for (; *format && length < max; ++format) | |
305 { | |
306 if (*format != '%') | |
307 add_char (*format); | |
308 else | |
309 { | |
310 ++format; | |
311 /* Modifiers: */ | |
312 if (*format == '-') | |
313 { | |
314 pad = none; | |
315 ++format; | |
316 } | |
317 else if (*format == '_') | |
318 { | |
319 pad = blank; | |
320 ++format; | |
321 } | |
322 else | |
323 pad = zero; | |
324 | |
325 switch (*format) | |
326 { | |
327 /* Literal character fields: */ | |
328 case 0: | |
329 case '%': | |
330 add_char ('%'); | |
331 break; | |
332 case 'n': | |
333 add_char ('\n'); | |
334 break; | |
335 case 't': | |
336 add_char ('\t'); | |
337 break; | |
338 default: | |
339 add_char (*format); | |
340 break; | |
341 | |
342 /* Time fields: */ | |
343 case 'H': | |
344 case 'k': | |
345 length += | |
346 add_num2 (&string[length], tm->tm_hour, max - length, | |
347 *format == 'H' ? pad : blank); | |
348 break; | |
349 case 'I': | |
350 case 'l': | |
351 { | |
352 int hour12; | |
353 | |
354 if (tm->tm_hour == 0) | |
355 hour12 = 12; | |
356 else if (tm->tm_hour > 12) | |
357 hour12 = tm->tm_hour - 12; | |
358 else | |
359 hour12 = tm->tm_hour; | |
360 length += | |
361 add_num2 (&string[length], hour12, max - length, | |
362 *format == 'I' ? pad : blank); | |
363 } | |
364 break; | |
365 case 'M': | |
366 length += | |
367 add_num2 (&string[length], tm->tm_min, max - length, pad); | |
368 break; | |
369 case 'p': | |
370 if (tm->tm_hour < 12) | |
371 add_char ('A'); | |
372 else | |
373 add_char ('P'); | |
374 add_char ('M'); | |
375 break; | |
376 case 'r': | |
377 length += | |
378 strftime (&string[length], max - length, "%I:%M:%S %p", tm); | |
379 break; | |
380 case 'R': | |
381 length += | |
382 strftime (&string[length], max - length, "%H:%M", tm); | |
383 break; | |
384 | |
385 case 's': | |
386 { | |
387 struct tm writable_tm; | |
388 writable_tm = *tm; | |
389 length += add_num_time_t (&string[length], max - length, | |
390 mktime (&writable_tm)); | |
391 } | |
392 break; | |
393 | |
394 case 'S': | |
395 length += | |
396 add_num2 (&string[length], tm->tm_sec, max - length, pad); | |
397 break; | |
398 case 'T': | |
399 length += | |
400 strftime (&string[length], max - length, "%H:%M:%S", tm); | |
401 break; | |
4203 | 402 |
403 case 'V': | |
404 case 'g': | |
405 case 'G': | |
406 { | |
407 int year = tm->tm_year + 1900; | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4203
diff
changeset
|
408 int ndays = iso_week_days (tm->tm_yday, tm->tm_wday); |
4203 | 409 |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4203
diff
changeset
|
410 if (ndays < 0) |
4203 | 411 { |
412 /* This ISO week belongs to the previous year. */ | |
413 year--; | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4203
diff
changeset
|
414 ndays = |
4203 | 415 iso_week_days (tm->tm_yday + (365 + __isleap (year)), |
416 tm->tm_wday); | |
417 } | |
418 else | |
419 { | |
420 int d = | |
421 iso_week_days (tm->tm_yday - (365 + __isleap (year)), | |
422 tm->tm_wday); | |
423 if (0 <= d) | |
424 { | |
425 /* This ISO week belongs to the next year. */ | |
426 year++; | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4203
diff
changeset
|
427 ndays = d; |
4203 | 428 } |
429 } | |
430 | |
431 switch (*format) | |
432 { | |
433 /* | |
434 #### FIXME | |
435 We really can't assume 1000 <= year <= 9999 | |
436 once time_t gets beyond 32 bits, but it's true | |
437 of the rest of the code here so get with the | |
438 program | |
439 */ | |
440 case 'g': | |
441 length += | |
442 add_num2 (&string[length], year % 100, | |
443 max - length, pad); | |
444 break; | |
445 | |
446 case 'G': | |
447 add_char (year / 1000 + '0'); | |
448 length += add_num3 (&string[length], year % 1000, | |
449 max - length, zero); | |
450 break; | |
451 | |
452 default: | |
453 length += | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4203
diff
changeset
|
454 add_num2 (&string[length], ndays / 7 + 1, |
4203 | 455 max - length, pad); |
456 break; | |
457 } | |
458 } | |
459 break; | |
428 | 460 case 'X': |
461 length += | |
462 strftime (&string[length], max - length, "%H:%M:%S", tm); | |
463 break; | |
4203 | 464 case 'z': |
465 { | |
466 /* | |
467 #### FIXME: could use tm->tm_gmtoff if present. Since | |
468 the other code in xemacs does not do so we follow the | |
469 leaders (and don't add a autoconf macro to detect | |
470 its presence). | |
471 */ | |
472 long int offset; | |
473 long int minutes; | |
474 struct tm lt, *ut; | |
475 time_t utc; | |
476 | |
477 lt = *tm; | |
478 utc = mktime(<); | |
479 ut = gmtime(&utc); | |
480 /* assume that tm is valid so the others will be too! */ | |
481 assert( utc != (time_t) -1 && ut != NULL ); | |
482 | |
483 /* tm diff code below is based on mktime.c, glibc 2.3.2 */ | |
484 { | |
485 int lt4, ut4, lt100, ut100, lt400, ut400; | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4203
diff
changeset
|
486 int intervening_leap_days, years, ndays; |
4203 | 487 |
488 lt4 = (lt.tm_year >> 2) + (1900 >> 2) - | |
489 ! (lt.tm_year & 3); | |
490 ut4 = (ut->tm_year >> 2) + (1900 >> 2) - | |
491 ! (ut->tm_year & 3); | |
492 lt100 = lt4 / 25 - (lt4 % 25 < 0); | |
493 ut100 = ut4 / 25 - (ut4 % 25 < 0); | |
494 lt400 = lt100 >> 2; | |
495 ut400 = ut100 >> 2; | |
496 intervening_leap_days = | |
497 (lt4 - ut4) - (lt100 - ut100) + (lt400 - ut400); | |
498 years = lt.tm_year - ut->tm_year; | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4203
diff
changeset
|
499 ndays = (365 * years + intervening_leap_days |
4203 | 500 + (lt.tm_yday - ut->tm_yday)); |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4203
diff
changeset
|
501 offset = (60 * (60 * (24 * ndays |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4203
diff
changeset
|
502 + (lt.tm_hour - ut->tm_hour)) |
4203 | 503 + (lt.tm_min - ut->tm_min)) |
504 + (lt.tm_sec - ut->tm_sec)); | |
505 } | |
506 | |
507 minutes = offset / ( offset < 0 ? -60 : 60 ); | |
508 | |
509 add_char ((offset < 0 ? '-' : '+')); | |
510 | |
511 if ( minutes / 600 != 0 ) | |
512 add_char (minutes / 600 + '0'); | |
513 else if ( pad != none ) | |
514 add_char ((pad == zero ? '0' : ' ')); | |
515 | |
516 length += | |
517 add_num3 (&string[length], | |
518 ((minutes / 60 ) % 10) * 100 + (minutes % 60), | |
519 max - length, pad); | |
520 break; | |
521 } | |
428 | 522 case 'Z': |
523 #ifdef HAVE_TM_ZONE | |
524 length += add_str (&string[length], tm->tm_zone, max - length); | |
525 #else | |
526 #ifdef HAVE_TZNAME | |
527 if (tm->tm_isdst && tzname[1] && *tzname[1]) | |
528 length += add_str (&string[length], tzname[1], max - length); | |
529 else | |
530 length += add_str (&string[length], tzname[0], max - length); | |
531 #else | |
532 length += add_str (&string[length], zone_name (tm), max - length); | |
533 #endif | |
534 #endif | |
535 break; | |
536 | |
537 /* Date fields: */ | |
538 case 'a': | |
539 add_char (days[tm->tm_wday][0]); | |
540 add_char (days[tm->tm_wday][1]); | |
541 add_char (days[tm->tm_wday][2]); | |
542 break; | |
543 case 'A': | |
544 length += | |
545 add_str (&string[length], days[tm->tm_wday], max - length); | |
546 break; | |
547 case 'b': | |
548 case 'h': | |
549 add_char (months[tm->tm_mon][0]); | |
550 add_char (months[tm->tm_mon][1]); | |
551 add_char (months[tm->tm_mon][2]); | |
552 break; | |
553 case 'B': | |
554 length += | |
555 add_str (&string[length], months[tm->tm_mon], max - length); | |
556 break; | |
557 case 'c': | |
558 length += | |
559 strftime (&string[length], max - length, | |
560 "%a %b %d %H:%M:%S %Z %Y", tm); | |
561 break; | |
562 case 'C': | |
563 length += | |
564 add_num2 (&string[length], (tm->tm_year + 1900) / 100, | |
565 max - length, pad); | |
566 break; | |
567 case 'd': | |
568 length += | |
569 add_num2 (&string[length], tm->tm_mday, max - length, pad); | |
570 break; | |
571 case 'e': | |
572 length += | |
573 add_num2 (&string[length], tm->tm_mday, max - length, blank); | |
574 break; | |
575 case 'D': | |
576 length += | |
577 strftime (&string[length], max - length, "%m/%d/%y", tm); | |
578 break; | |
579 case 'j': | |
580 length += | |
581 add_num3 (&string[length], tm->tm_yday + 1, max - length, pad); | |
582 break; | |
583 case 'm': | |
584 length += | |
585 add_num2 (&string[length], tm->tm_mon + 1, max - length, pad); | |
586 break; | |
587 case 'U': | |
588 length += | |
589 add_num2 (&string[length], sun_week (tm), max - length, pad); | |
590 break; | |
591 case 'w': | |
592 add_char (tm->tm_wday + '0'); | |
593 break; | |
594 case 'W': | |
595 length += | |
596 add_num2 (&string[length], mon_week (tm), max - length, pad); | |
597 break; | |
598 case 'x': | |
599 length += | |
600 strftime (&string[length], max - length, "%m/%d/%y", tm); | |
601 break; | |
602 case 'y': | |
603 length += | |
604 add_num2 (&string[length], tm->tm_year % 100, | |
605 max - length, pad); | |
606 break; | |
607 case 'Y': | |
608 add_char ((tm->tm_year + 1900) / 1000 + '0'); | |
609 length += | |
610 add_num3 (&string[length], | |
611 (1900 + tm->tm_year) % 1000, max - length, zero); | |
612 break; | |
5254
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
613 case '\xe6': |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
614 length += |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
615 add_str (&string[length], roman_lower[tm->tm_mon], |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
616 max - length); |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
617 break; |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
618 case '\xC6': |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
619 length += |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
620 add_str (&string[length], roman_upper[tm->tm_mon], |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
621 max - length); |
1537701f08a1
Support Roman month numbers, #'format-time-string
Aidan Kehoe <kehoea@parhasard.net>
parents:
5016
diff
changeset
|
622 break; |
428 | 623 } |
624 } | |
625 } | |
626 add_char (0); | |
627 return length - 1; | |
628 } |