Mercurial > hg > xemacs-beta
comparison src/strftime.c @ 5118:e0db3c197671 ben-lisp-object
merge up to latest default branch, doesn't compile yet
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Sat, 26 Dec 2009 21:18:49 -0600 |
parents | 0a63e5de7bdc |
children | 2ade80e8c640 |
comparison
equal
deleted
inserted
replaced
5117:3742ea8250b5 | 5118:e0db3c197671 |
---|---|
56 %R time, 24-hour (hh:mm) | 56 %R time, 24-hour (hh:mm) |
57 %s time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension) | 57 %s time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension) |
58 %S second (00..61) | 58 %S second (00..61) |
59 %T time, 24-hour (hh:mm:ss) | 59 %T time, 24-hour (hh:mm:ss) |
60 %X locale's time representation (%H:%M:%S) | 60 %X locale's time representation (%H:%M:%S) |
61 %z time zone offset (e.g. +0530, -0800 etc) | |
61 %Z time zone (EDT), or nothing if no time zone is determinable | 62 %Z time zone (EDT), or nothing if no time zone is determinable |
62 | 63 |
63 Date fields: | 64 Date fields: |
64 %a locale's abbreviated weekday name (Sun..Sat) | 65 %a locale's abbreviated weekday name (Sun..Sat) |
65 %A locale's full weekday name, variable length (Sunday..Saturday) | 66 %A locale's full weekday name, variable length (Sunday..Saturday) |
68 %c locale's date and time (Sat Nov 04 12:02:33 EST 1989) | 69 %c locale's date and time (Sat Nov 04 12:02:33 EST 1989) |
69 %C century (00..99) | 70 %C century (00..99) |
70 %d day of month (01..31) | 71 %d day of month (01..31) |
71 %e day of month ( 1..31) | 72 %e day of month ( 1..31) |
72 %D date (mm/dd/yy) | 73 %D date (mm/dd/yy) |
74 %G year corresponding to the ISO 8601 week | |
75 %g Year of the ISO 8601 week within century (00 - 99) | |
73 %h same as %b | 76 %h same as %b |
74 %j day of year (001..366) | 77 %j day of year (001..366) |
75 %m month (01..12) | 78 %m month (01..12) |
76 %U week number of year with Sunday as first day of week (00..53) | 79 %U week number of year with Sunday as first day of week (00..53) |
80 %V ISO 8601 week number (first week is the earliest one with Thu) | |
77 %w day of week (0..6) | 81 %w day of week (0..6) |
78 %W week number of year with Monday as first day of week (00..53) | 82 %W week number of year with Monday as first day of week (00..53) |
79 %x locale's date representation (mm/dd/yy) | 83 %x locale's date representation (mm/dd/yy) |
80 %y last two digits of year (00..99) | 84 %y last two digits of year (00..99) |
81 %Y year (1970...) | 85 %Y year (1970...) |
231 wday = 6; | 235 wday = 6; |
232 else | 236 else |
233 wday = tm->tm_wday - 1; | 237 wday = tm->tm_wday - 1; |
234 dl = tm->tm_yday - wday; | 238 dl = tm->tm_yday - wday; |
235 return dl <= 0 ? 0 : dl / 7 + (dl % 7 != 0); | 239 return dl <= 0 ? 0 : dl / 7 + (dl % 7 != 0); |
240 } | |
241 | |
242 #ifndef __isleap | |
243 /* Nonzero if YEAR is a leap year (every 4 years, | |
244 except every 100th isn't, and every 400th is). */ | |
245 # define __isleap(year) \ | |
246 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) | |
247 #endif | |
248 | |
249 /* The number of days from the first day of the first ISO week of this | |
250 year to the year day YDAY with week day WDAY. ISO weeks start on | |
251 Monday; the first ISO week has the year's first Thursday. YDAY may | |
252 be as small as YDAY_MINIMUM. */ | |
253 #define ISO_WEEK_START_WDAY 1 /* Monday */ | |
254 #define ISO_WEEK1_WDAY 4 /* Thursday */ | |
255 #define YDAY_MINIMUM (-366) | |
256 static int | |
257 iso_week_days (int yday, int wday) | |
258 { | |
259 /* Add enough to the first operand of % to make it nonnegative. */ | |
260 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7; | |
261 return (yday | |
262 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7 | |
263 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY); | |
236 } | 264 } |
237 | 265 |
238 #if !defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME) | 266 #if !defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME) |
239 char *zone_name (const struct tm *tp); | 267 char *zone_name (const struct tm *tp); |
240 char * | 268 char * |
360 break; | 388 break; |
361 case 'T': | 389 case 'T': |
362 length += | 390 length += |
363 strftime (&string[length], max - length, "%H:%M:%S", tm); | 391 strftime (&string[length], max - length, "%H:%M:%S", tm); |
364 break; | 392 break; |
393 | |
394 case 'V': | |
395 case 'g': | |
396 case 'G': | |
397 { | |
398 int year = tm->tm_year + 1900; | |
399 int days = iso_week_days (tm->tm_yday, tm->tm_wday); | |
400 | |
401 if (days < 0) | |
402 { | |
403 /* This ISO week belongs to the previous year. */ | |
404 year--; | |
405 days = | |
406 iso_week_days (tm->tm_yday + (365 + __isleap (year)), | |
407 tm->tm_wday); | |
408 } | |
409 else | |
410 { | |
411 int d = | |
412 iso_week_days (tm->tm_yday - (365 + __isleap (year)), | |
413 tm->tm_wday); | |
414 if (0 <= d) | |
415 { | |
416 /* This ISO week belongs to the next year. */ | |
417 year++; | |
418 days = d; | |
419 } | |
420 } | |
421 | |
422 switch (*format) | |
423 { | |
424 /* | |
425 #### FIXME | |
426 We really can't assume 1000 <= year <= 9999 | |
427 once time_t gets beyond 32 bits, but it's true | |
428 of the rest of the code here so get with the | |
429 program | |
430 */ | |
431 case 'g': | |
432 length += | |
433 add_num2 (&string[length], year % 100, | |
434 max - length, pad); | |
435 break; | |
436 | |
437 case 'G': | |
438 add_char (year / 1000 + '0'); | |
439 length += add_num3 (&string[length], year % 1000, | |
440 max - length, zero); | |
441 break; | |
442 | |
443 default: | |
444 length += | |
445 add_num2 (&string[length], days / 7 + 1, | |
446 max - length, pad); | |
447 break; | |
448 } | |
449 } | |
450 break; | |
365 case 'X': | 451 case 'X': |
366 length += | 452 length += |
367 strftime (&string[length], max - length, "%H:%M:%S", tm); | 453 strftime (&string[length], max - length, "%H:%M:%S", tm); |
368 break; | 454 break; |
455 case 'z': | |
456 { | |
457 /* | |
458 #### FIXME: could use tm->tm_gmtoff if present. Since | |
459 the other code in xemacs does not do so we follow the | |
460 leaders (and don't add a autoconf macro to detect | |
461 its presence). | |
462 */ | |
463 long int offset; | |
464 long int minutes; | |
465 struct tm lt, *ut; | |
466 time_t utc; | |
467 | |
468 lt = *tm; | |
469 utc = mktime(<); | |
470 ut = gmtime(&utc); | |
471 /* assume that tm is valid so the others will be too! */ | |
472 assert( utc != (time_t) -1 && ut != NULL ); | |
473 | |
474 /* tm diff code below is based on mktime.c, glibc 2.3.2 */ | |
475 { | |
476 int lt4, ut4, lt100, ut100, lt400, ut400; | |
477 int intervening_leap_days, years, days; | |
478 | |
479 lt4 = (lt.tm_year >> 2) + (1900 >> 2) - | |
480 ! (lt.tm_year & 3); | |
481 ut4 = (ut->tm_year >> 2) + (1900 >> 2) - | |
482 ! (ut->tm_year & 3); | |
483 lt100 = lt4 / 25 - (lt4 % 25 < 0); | |
484 ut100 = ut4 / 25 - (ut4 % 25 < 0); | |
485 lt400 = lt100 >> 2; | |
486 ut400 = ut100 >> 2; | |
487 intervening_leap_days = | |
488 (lt4 - ut4) - (lt100 - ut100) + (lt400 - ut400); | |
489 years = lt.tm_year - ut->tm_year; | |
490 days = (365 * years + intervening_leap_days | |
491 + (lt.tm_yday - ut->tm_yday)); | |
492 offset = (60 * (60 * (24 * days + (lt.tm_hour - ut->tm_hour)) | |
493 + (lt.tm_min - ut->tm_min)) | |
494 + (lt.tm_sec - ut->tm_sec)); | |
495 } | |
496 | |
497 minutes = offset / ( offset < 0 ? -60 : 60 ); | |
498 | |
499 add_char ((offset < 0 ? '-' : '+')); | |
500 | |
501 if ( minutes / 600 != 0 ) | |
502 add_char (minutes / 600 + '0'); | |
503 else if ( pad != none ) | |
504 add_char ((pad == zero ? '0' : ' ')); | |
505 | |
506 length += | |
507 add_num3 (&string[length], | |
508 ((minutes / 60 ) % 10) * 100 + (minutes % 60), | |
509 max - length, pad); | |
510 break; | |
511 } | |
369 case 'Z': | 512 case 'Z': |
370 #ifdef HAVE_TM_ZONE | 513 #ifdef HAVE_TM_ZONE |
371 length += add_str (&string[length], tm->tm_zone, max - length); | 514 length += add_str (&string[length], tm->tm_zone, max - length); |
372 #else | 515 #else |
373 #ifdef HAVE_TZNAME | 516 #ifdef HAVE_TZNAME |