Mercurial > hg > xemacs-beta
annotate src/strftime.c @ 5658:289cf21be887
Don't augment ENVIRONMENT when that's not indicated, #'macroexpand.
This reflects better understanding on my part of the &environment macro
keyword, and I've expanded the Lisp manual and docstrings to reflect that.
lisp/ChangeLog addition:
2012-05-06 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el (block): Comment on why we can't use &environment
here.
* cl-macs.el (defmacro*): Document &environment in more detail.
* cl-macs.el (macrolet): Use &environment, instead of referencing
byte-compile-macro-environment directly.
* cl-macs.el (symbol-macrolet): Ditto.
* cl-macs.el (lexical-let): Ditto.
* cl-macs.el (labels): Ditto.
man/ChangeLog addition:
2012-05-06 Aidan Kehoe <kehoea@parhasard.net>
* lispref/macros.texi (Expansion):
Cross-reference to documentation of #'cl-prettyexpand, #'defmacro*
when talking about #'macroexpand.
tests/ChangeLog addition:
2012-05-06 Aidan Kehoe <kehoea@parhasard.net>
* automated/lisp-tests.el:
Use &environment appropriately in #'macrolet, instead of relying
on #'macroexpand to guess what we mean.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sun, 06 May 2012 15:29:59 +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 } |