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