X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fstrftime.c;h=e6b0c5a47c3caa995b2fcb349ea7e496ad6226e5;hb=692c4b6ea764fd34a53142b53c53a2d54b33ae6a;hp=cfd41adbee8ba1a6c94d4a570df30e7ff70d3aca;hpb=cd47583be488a600699606197091077ba4cb2c1d;p=gnulib.git diff --git a/lib/strftime.c b/lib/strftime.c index cfd41adbe..e6b0c5a47 100644 --- a/lib/strftime.c +++ b/lib/strftime.c @@ -46,9 +46,11 @@ %p locale's AM or PM %r time, 12-hour (hh:mm:ss [AP]M) %R time, 24-hour (hh:mm) + %s time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension) %S second (00..61) %T time, 24-hour (hh:mm:ss) %X locale's time representation (%H:%M:%S) + %z RFC-822 style numeric timezone (-0500) (a nonstandard extension) %Z time zone (EDT), or nothing if no time zone is determinable Date fields: @@ -73,6 +75,11 @@ David MacKenzie */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include #include #if defined(TM_IN_SYS_TIME) || (!defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME)) #include @@ -80,6 +87,10 @@ #include #endif +#ifndef STDC_HEADERS +time_t mktime (); +#endif + #if defined(HAVE_TZNAME) extern char *tzname[2]; #endif @@ -164,7 +175,7 @@ add_num3 (string, num, max, pad) static int add_str (to, from, max) char *to; - char *from; + const char *from; int max; { int i; @@ -174,6 +185,54 @@ add_str (to, from, max) return i; } +static int +add_num_time_t (string, max, num) + char *string; + int max; + time_t num; +{ + /* This buffer is large enough to hold the character representation + (including the trailing NUL) of any unsigned decimal quantity + whose binary representation fits in 128 bits. */ + char buf[40]; + int length; + + if (sizeof (num) > 16) + abort (); + sprintf (buf, "%lu", (unsigned long) num); + length = add_str (string, buf, max); + return length; +} + +/* Convert MINUTES_EAST into a string suitable for use as the RFC-822 + timezone indicator. Write no more than MAX bytes into STRING. + Return the number of bytes written into STRING. */ + +static int +add_num_tz (string, max, minutes_east) + char *string; + int max; + int minutes_east; +{ + int length; + + if (max < 1) + return 0; + + if (minutes_east < 0) + { + *string = '-'; + minutes_east = -minutes_east; + } + else + *string = '+'; + + length = 1 + add_num2 (&string[1], (minutes_east / 60) % 24, max - 1, zero); + length += add_num2 (&string[length], minutes_east % 60, max - length, zero); + + return length; +} + /* Return the week in the year of the time in TM, with the weeks starting on Sundays. */ @@ -319,6 +378,16 @@ strftime (string, max, format, tm) length += strftime (&string[length], max - length, "%H:%M", tm); break; + + case 's': + { + struct tm writable_tm; + writable_tm = *tm; + length += add_num_time_t (&string[length], max - length, + mktime (&writable_tm)); + } + break; + case 'S': length += add_num2 (&string[length], tm->tm_sec, max - length, pad); @@ -331,6 +400,37 @@ strftime (string, max, format, tm) length += strftime (&string[length], max - length, "%H:%M:%S", tm); break; + case 'z': + { + time_t t; + struct tm tml, tmg; + int diff; + + tml = *tm; + t = mktime (&tml); + tml = *localtime (&t); /* Canonicalize the local time */ + tmg = *gmtime (&t); + + /* Compute the difference */ + + diff = tml.tm_min - tmg.tm_min; + diff += 60 * (tml.tm_hour - tmg.tm_hour); + + if (tml.tm_mon != tmg.tm_mon) + { + /* We assume no timezone differs from UTC by more than + +- 23 hours. This should be safe. */ + if (tmg.tm_mday == 1) + tml.tm_mday = 0; + else /* tml.tm_mday == 1 */ + tmg.tm_mday = 0; + } + + diff += 1440 * (tml.tm_mday - tmg.tm_mday); + + length += add_num_tz (&string[length], max - length, diff); + } + break; case 'Z': #ifdef HAVE_TM_ZONE length += add_str (&string[length], tm->tm_zone, max - length);