From archie@packetdesign.com  Tue Sep  4 14:01:07 2001
Return-Path: <archie@packetdesign.com>
Received: from mailman.packetdesign.com (dns.packetdesign.com [65.192.41.10])
	by hub.freebsd.org (Postfix) with ESMTP id 6757137B40C
	for <FreeBSD-gnats-submit@freebsd.org>; Tue,  4 Sep 2001 14:01:05 -0700 (PDT)
Received: from bubba.packetdesign.com (bubba.packetdesign.com [192.168.0.223])
	by mailman.packetdesign.com (8.11.0/8.11.0) with ESMTP id f84L12222300
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 4 Sep 2001 14:01:02 -0700 (PDT)
	(envelope-from archie@packetdesign.com)
Received: (from archie@localhost)
	by bubba.packetdesign.com (8.11.3/8.11.1) id f84L12873812;
	Tue, 4 Sep 2001 14:01:02 -0700 (PDT)
	(envelope-from archie)
Message-Id: <200109042101.f84L12873812@bubba.packetdesign.com>
Date: Tue, 4 Sep 2001 14:01:02 -0700 (PDT)
From: Archie Cobbs <archie@packetdesign.com>
Reply-To: archie@packetdesign.com
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: strftime(3) '%s' format does not work properly
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         30321
>Category:       kern
>Synopsis:       [patch] strftime(3) '%s' format does not work properly
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Sep 04 14:10:01 PDT 2001
>Closed-Date:    
>Last-Modified:  Mon Sep 29 03:31:32 UTC 2008
>Originator:     Archie Cobbs
>Release:        FreeBSD 4.3-RELEASE i386
>Organization:
Packet Design
>Environment:
System: FreeBSD bubba.packetdesign.com 4.3-RELEASE FreeBSD 4.3-RELEASE #0: Thu Apr 26 15:28:39 PDT 2001 root@bubba.packetdesign.com:/usr/obj/usr/src/sys/BUBBA i386


>Description:

	The strftime(3) '%s' format is supposed to convert a
	'struct tm' into the number of seconds since the epoch
	(1/1/70 GMT).

	When it does this conversion, it uses the currently set
	system time zone instead of using the time zone from the
	'struct tm' argument. Therefore, if the two timezones are
	different, incorrect results are computed.

>How-To-Repeat:

	Run this program with your system time zone set to
	any timezone other than GMT. Notice that the value
	printed for "now" is different before and after the
	converstion.

	#include <sys/types.h>
	#include <sys/time.h>
	#include <stdio.h>
	#include <stdlib.h>
	#include <unistd.h>
	#include <time.h>

	int
	main(int ac, char **av)
	{
		time_t now;
		char buf[32];

		now = time(NULL);
		printf("now = %lu\n", (u_long)now);
		strftime(buf, sizeof(buf), "%s", gmtime(&now));
		printf("now = %s\n", buf);
		return (0);
	}

>Fix:

	I think this should fix it. From the timegm(3) man
	page, "The tm_isdst and tm_gmtoff members are forced
	to zero by timegm()" which I guess means that the
	value of 'tm_gmtoff' is added into the computation
	before being forced to zero.

Index: strftime.c
===================================================================
RCS file: /home/cvs/freebsd/src/lib/libc/stdtime/strftime.c,v
retrieving revision 1.25.2.3
diff -u -r1.25.2.3 strftime.c
--- strftime.c	2001/02/18 04:06:49	1.25.2.3
+++ strftime.c	2001/09/04 20:58:27
@@ -244,7 +244,7 @@
 					time_t		mkt;
 
 					tm = *t;
-					mkt = mktime(&tm);
+					mkt = timegm(&tm);
 					if (TYPE_SIGNED(time_t))
 						(void) sprintf(buf, "%ld",
 							(long) mkt);


>Release-Note:
>Audit-Trail:

From: Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
To: archie@packetdesign.com
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: bin/30321: strftime(3) '%s' format does not work properly
Date: Tue, 4 Sep 2001 17:52:18 -0400 (EDT)

 <<On Tue, 4 Sep 2001 14:01:02 -0700 (PDT), Archie Cobbs <archie@packetdesign.com> said:
 
 > 	When it does this conversion, it uses the currently set
 > 	system time zone instead of using the time zone from the
 > 	'struct tm' argument. Therefore, if the two timezones are
 > 	different, incorrect results are computed.
 
 This behavior is correct.  In the general case, as codified in the ISO
 C standard, `struct tm' does not contain time zone information.  ISO C
 functions such as strftime() are specified to use the system's time
 zone.
 
 Having said that, `%s' is not specified in either POSIX or ISO C, so
 we are free to make it mean anything we want.
 
 -GAWollman
 

From: Archie Cobbs <archie@packetdesign.com>
To: Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: bin/30321: strftime(3) '%s' format does not work properly
Date: Tue, 04 Sep 2001 16:42:38 -0700

 Garrett Wollman wrote:
 > >       When it does this conversion, it uses the currently set
 > >       system time zone instead of using the time zone from the
 > >       'struct tm' argument. Therefore, if the two timezones are
 > >       different, incorrect results are computed.
 > 
 > This behavior is correct.  In the general case, as codified in the ISO
 > C standard, `struct tm' does not contain time zone information.  ISO C
 > functions such as strftime() are specified to use the system's time
 > zone.
 
 The current behavior of '%s' is inconsistent with every other
 format character supported by strftime(3). For example, if you
 use '%z' you get the time zone offset read directly from the struct tm;
 the system time zone has no effect on that conversion whatsoever.
 Same for '%H', etc.
 
 So at best, it violates POLA and is bizarre, undocumented behavior.
 
 -Archie
 
 __________________________________________________________________________
 Archie Cobbs     *     Packet Design     *     http://www.packetdesign.com

From: Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
To: Archie Cobbs <archie@packetdesign.com>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: bin/30321: strftime(3) '%s' format does not work properly
Date: Tue, 4 Sep 2001 20:46:42 -0400 (EDT)

 <<On Tue, 04 Sep 2001 16:42:38 -0700, Archie Cobbs <archie@packetdesign.com> said:
 
 > For example, if you use '%z' you get the time zone offset read
 > directly from the struct tm; the system time zone has no effect on
 > that conversion whatsoever.
 
 This is a bug.  POSIX says that ``Local timezone information is used
 as though strftime( ) called tzset( ).''  POSIX does not appear to
 permit the implementation to require initialization of non-standard
 fields in `struct tm' for strftime() to work.  I would interpret the
 specification as requiring that strftime() always use the ``system''
 timezone.  In order for our implementation to meet the specification,
 we need to call mktime() on a copy of the input structure in order to
 determine the timezone to generate for `%z' and `%Z'.
 
 -GAWollman
 
>Unformatted:
