From: Jason Green Newsgroups: comp.os.msdos.djgpp Subject: Re: strftime: Need Help with Time Offsets Date: Wed, 20 Dec 2000 20:54:29 +0000 Organization: Customer of Energis Squared Lines: 133 Message-ID: <1a524t0tk28cmv3vqfq26tooe0qeikhgm5@4ax.com> References: <3a39c060 DOT 1329770 AT corp DOT supernews DOT net> NNTP-Posting-Host: modem-62.medroxyprogest.dialup.pol.co.uk Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: news5.svr.pol.co.uk 977345687 7687 62.136.88.190 (20 Dec 2000 20:54:47 GMT) NNTP-Posting-Date: 20 Dec 2000 20:54:47 GMT X-Complaints-To: abuse AT theplanet DOT net X-Newsreader: Forte Agent 1.7/32.534 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com ftilley AT azstarnet DOT cyberbromo DOT com (Felix Tilley) wrote: > All of the GMT offsets are wrong. Dates and times are correct, but > the GMT offsets are wrong. There appears to be a bug in strftime() when using the %z format. Well, actually not so much a bug as a feature. ;-) At the moment, the number of seconds offset from GMT is used, unless it is negative, in which case 0000 is used. I've patched strftime.c to fix this. The patch is attached at the bottom of this message. There is also some more test code to demonstrate the problem. Note: The original code posted by Felix, poked values into the tm_gmtoff and tm_zone fields to simulate a time-zone shift. I don't know if that's a valid method (mktime() seems to reset those fields without using their values) but it works well enough as a test case for this patch. With existing strftime the test program outputs: Wed, 20 Dec 2000 20:35:42 +0000 GMT Wed, 20 Dec 2000 20:35:42 +0000 GMT Wed, 20 Dec 2000 08:01:42 -0000 TEST1 Thu, 21 Dec 2000 09:09:42 +45240 TEST2 After patching the test program outputs: Wed, 20 Dec 2000 20:36:21 +0000 GMT Wed, 20 Dec 2000 20:36:21 +0000 GMT Wed, 20 Dec 2000 08:02:21 -1234 TEST1 Thu, 21 Dec 2000 09:10:21 +1234 TEST2 Here is the test program: /******************* start of test code ********************/ #include #include #include #include void PrintTime(const char *fmt, const struct tm *tm); int main(void) { time_t now; struct tm *tm; const char *fmt = "%a, %d %b %Y %X %z %Z"; time(&now); PrintTime(fmt, gmtime(&now)); PrintTime(fmt, localtime(&now)); tm = gmtime(&now); tm->tm_hour -= 12; tm->tm_min -= 34; tm->tm_gmtoff = difftime(mktime(tm), now); tm->tm_zone = "TEST1"; PrintTime(fmt, tm); tm = gmtime(&now); tm->tm_hour += 12; tm->tm_min += 34; tm->tm_gmtoff = difftime(mktime(tm), now); tm->tm_zone = "TEST2"; PrintTime(fmt, tm); return 0; } void PrintTime(const char *fmt, const struct tm *tm) { char str[256]; if (strftime(str, sizeof(str), fmt, tm) > 0) puts(str); else puts("oops!"); } /******************* end of test code ********************/ Here is the patch: --- src/libc/ansi/time/strftime.c.orig Thu Jun 3 13:27:34 1999 +++ src/libc/ansi/time/strftime.c Wed Dec 20 19:25:00 2000 @@ -61,6 +61,8 @@ static size_t _fmt(const char *format, const struct tm *t, int upcase) { + long gmtoffset, gmtoffset_mins, gmtoffset_hrs; + for (; *format; ++format) { if (*format == '%') @@ -218,10 +220,23 @@ return 0; continue; case 'z': - if (!_add(t->__tm_gmtoff<0 ? "-" : "+", 0)) - return 0; - if (!_conv(t->__tm_gmtoff, 4, pad)) - return 0; + gmtoffset_mins = (t->__tm_gmtoff / 60) % 60; + gmtoffset_hrs = t->__tm_gmtoff / 3600; + gmtoffset = (gmtoffset_hrs * 100) + gmtoffset_mins; + if (gmtoffset<0) + { + if (!_add("-", 0)) + return 0; + if (!_conv(-gmtoffset, 4, pad)) + return 0; + } + else + { + if (!_add("+", 0)) + return 0; + if (!_conv(gmtoffset, 4, pad)) + return 0; + } continue; case 'Z': if (!t->tm_zone || !_add(t->tm_zone, upcase))