From maxim@news1.macomnet.ru  Thu Jun 21 00:22:30 2001
Return-Path: <maxim@news1.macomnet.ru>
Received: from news1.macomnet.ru (news1.macomnet.ru [195.128.64.14])
	by hub.freebsd.org (Postfix) with ESMTP id 81F1637B401
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 21 Jun 2001 00:22:29 -0700 (PDT)
	(envelope-from maxim@news1.macomnet.ru)
Received: (from maxim@localhost)
	by news1.macomnet.ru (8.11.1/8.11.1) id f5L7MRJ29127;
	Thu, 21 Jun 2001 11:22:27 +0400 (MSD)
	(envelope-from maxim)
Message-Id: <200106210722.f5L7MRJ29127@news1.macomnet.ru>
Date: Thu, 21 Jun 2001 11:22:27 +0400 (MSD)
From: maxim@macomnet.ru
Reply-To: maxim@macomnet.ru
To: FreeBSD-gnats-submit@freebsd.org
Subject: /bin/date -f is broken
X-Send-Pr-Version: 3.2

>Number:         28313
>Category:       bin
>Synopsis:       /bin/date -f is broken
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    ru
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jun 21 00:30:01 PDT 2001
>Closed-Date:    Sat Jun 23 01:57:48 PDT 2001
>Last-Modified:  Sat Jun 23 01:59:25 PDT 2001
>Originator:     Maxim Konovalov
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
>Environment:

	FreeBSD 5.0-CURRENT
	FreeBSD 4.3-STABLE

>Description:

	/bin/date -f is broken. Please take a look at
	How-To-Repeat section.

>How-To-Repeat:

	# date 200105310101
	Thu May 31 01:01:00 MSD 2001
	$ date -j -f "%m" 2 "+%b"
	Mar
	$ date -j -f "%m" 3 "+%b"
	Mar

>Fix:

Here is my hack, but AFAIK ru@freebsd.org has a more generic solution.

--- date.c.orig	Thu May 31 05:59:07 2001
+++ date.c	Thu May 31 05:58:31 2001
@@ -192,6 +192,7 @@
 
 	if (fmt != NULL) {
 		lt = localtime(&tval);
+		lt->tm_mday = 1;
 		t = strptime(p, fmt, lt);
 		if (t == NULL) {
 			fprintf(stderr, "Failed conversion of ``%s''"
>Release-Note:
>Audit-Trail:

From: Ruslan Ermilov <ru@FreeBSD.org>
To: maxim@macomnet.ru
Cc: bug-followup@FreeBSD.org
Subject: Re: bin/28313: /bin/date -f is broken
Date: Thu, 21 Jun 2001 11:16:20 +0300

 On Thu, Jun 21, 2001 at 11:22:27AM +0400, maxim@macomnet.ru wrote:
 > 
 > /bin/date -f is broken. Please take a look at
 > How-To-Repeat section.
 > 
 > # date 200105310101
 > Thu May 31 01:01:00 MSD 2001
 > $ date -j -f "%m" 2 "+%b"
 > Mar
 > $ date -j -f "%m" 3 "+%b"
 > Mar
 > 
 > Here is my hack, but AFAIK ru@freebsd.org has a more generic solution.
 > 
 > --- date.c.orig	Thu May 31 05:59:07 2001
 > +++ date.c	Thu May 31 05:58:31 2001
 > @@ -192,6 +192,7 @@
 >  
 >  	if (fmt != NULL) {
 >  		lt = localtime(&tval);
 > +		lt->tm_mday = 1;
 >  		t = strptime(p, fmt, lt);
 >  		if (t == NULL) {
 >  			fprintf(stderr, "Failed conversion of ``%s''"
 > 
 The below patch would do the trick, but I'm not sure this is the right
 thing.  This will "fold" tm_mday into the largest possible for this
 tm_year and tm_mon, instead of current "add-with-carry" operation.
 
 Both ISO C and POSIX are silent on this, and only mention that
 "the original values of the tm_wday and tm_yday components of
 the structure are ignored, and the original values of the other
 components are not restricted to the ranges described in <time.h>",
 and that "upon successful completion, the values of the tm_wday
 and tm_yday components of the structure shall be set appropriately,
 and the other components are set to represent the specified time
 since the Epoch, but with their values forced to the ranges
 indicated in the <time.h> entry; the final value of tm_mday shall
 not be set until tm_mon and tm_year are determined."
 
 It is unspecified as to whether the implementation should
 "add-with-the-carry" or "fold" the values that are out of range.
 
 Both OpenBSD and NetBSD behave the same, as we share the same
 code.
 
 Linux behaves the same:
 
 : If structure members are outside their legal interval, they
 : will be normalized (so that, e.g., 40 October is changed into
 : 9 November).
 
 System V Release 5 behaves the same:
 
 : The original values of the components may be either greater than or
 : less than the specified range. For example, a tm_hour of -1 means 1
 : hour before midnight, tm_mday of 0 means the day preceding the current
 : month, and tm_mon of -2 means 2 months before January of tm_year.
 
 SUSv2 simply derived their mktime() from POSIX.1-1988.
 
 It sounds to me that we should document the "add-with-carry" behavior
 and leave things AS IS.
 
 
 Index: localtime.c
 ===================================================================
 RCS file: /home/ncvs/src/lib/libc/stdtime/localtime.c,v
 retrieving revision 1.28
 diff -u -p -r1.28 localtime.c
 --- localtime.c	2001/06/05 20:13:28	1.28
 +++ localtime.c	2001/06/21 07:42:27
 @@ -1440,12 +1440,16 @@ int * const		okayp;
  		i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon];
  		if (yourtm.tm_mday <= i)
  			break;
 +#if 0
  		yourtm.tm_mday -= i;
  		if (++yourtm.tm_mon >= MONSPERYEAR) {
  			yourtm.tm_mon = 0;
  			if (increment_overflow(&yourtm.tm_year, 1))
  				return WRONG;
  		}
 +#else
 +		yourtm.tm_mday = i;
 +#endif
  	}
  	if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE))
  		return WRONG;
 
 -- 
 Ruslan Ermilov		Oracle Developer/DBA,
 ru@sunbay.com		Sunbay Software AG,
 ru@FreeBSD.org		FreeBSD committer,
 +380.652.512.251	Simferopol, Ukraine
 
 http://www.FreeBSD.org	The Power To Serve
 http://www.oracle.com	Enabling The Information Age

From: Bruce Evans <bde@zeta.org.au>
To: Ruslan Ermilov <ru@FreeBSD.ORG>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: bin/28313: /bin/date -f is broken
Date: Thu, 21 Jun 2001 20:06:45 +1000 (EST)

 On Thu, 21 Jun 2001, Ruslan Ermilov wrote:
 
 >  Both ISO C and POSIX are silent on this, and only mention that
 >  "the original values of the tm_wday and tm_yday components of
 >  the structure are ignored, and the original values of the other
 >  components are not restricted to the ranges described in <time.h>",
 >  and that "upon successful completion, the values of the tm_wday
 >  and tm_yday components of the structure shall be set appropriately,
 >  and the other components are set to represent the specified time
 >  since the Epoch, but with their values forced to the ranges
 >  indicated in the <time.h> entry; the final value of tm_mday shall
 >  not be set until tm_mon and tm_year are determined."
 
 ISO C is fuzzier than I remembered about this, but POSIX.1 is unsilent
 and clearly requires "add-with-carry" behaviour.  From the 200x version:
 
 25103              The relationship between the tm structure (defined in
                    the <time.h> header) and the time in
 25104              seconds since the Epoch is that the result shall be as
                    specified in the expression given in the
 25105              definition of seconds since the Epoch (see the Base
                    Definitions volume of IEEE Std 1003.1-200x,
 25106              Section 4.14, Seconds Since the Epoch) corrected for
                    timezone and any seasonal time
 25107              adjustments, where the names in the structure and in
                    the expression correspond.
 
 Previous lines say the same things as the part of the ISO C standard that
 you quoted.  In particular, most of the components of the tm struct are
 not restricted in the usual way.  The above applies even to such values
 and is equivalent to specifiying "add-with-carry" behaviour.
 
 >  It sounds to me that we should document the "add-with-carry" behavior
 >  and leave things AS IS.
 
 I agree.  Not as in your patch :-).
 
 Bruce
 
State-Changed-From-To: open->closed 
State-Changed-By: ru 
State-Changed-When: Sat Jun 23 01:57:48 PDT 2001 
State-Changed-Why:  
Normalizing behavior of mktime(3) documented in ctime.3,v 1.15. 
MFC in 1 week. 


Responsible-Changed-From-To: freebsd-bugs->ru 
Responsible-Changed-By: ru 
Responsible-Changed-When: Sat Jun 23 01:57:48 PDT 2001 
Responsible-Changed-Why:  
++Responsible[ru] 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=28313 
>Unformatted:
