
> The time zone is now evaluated in the time zone of the result, rather
> than the input, using system support routines from libc. 

Ok, I have the answer.

On AIX mktime(3) leaves tm_isdst at -1 if it does not have timezone 
info for that particular year and returns -1.
>From man page:
	The mktime subroutine returns the specified time in seconds encoded as a value of
	type time_t. If the time cannot be represented, the function returns the value
	(time_t)-1.

The following code then makes savings time out of the -1.
                                        tz = (tm->tm_isdst ? (timezone - 3600) : timezone);

What now ?

Andreas

Wed, 10 Jan 2001 11:28:45 +0100
Zeugswetter Andreas SB  <ZeugswetterA@wien.spardat.at>
AW: Re: tinterval - operator problems on AIX
> On AIX mktime(3) leaves tm_isdst at -1 if it does not have timezone
> info for that particular year and returns -1.
> The following code then makes savings time out of the -1.
>   tz = (tm->tm_isdst ? (timezone - 3600) : timezone);

Hmm. That description is consistant with what I see in the Linux man
page. So I should check for (tm->tm_isdst > 0) rather than checking for
non-zero?

Would you like to test that on your machine? I'll try it here, and if
successful will consider this a bug report and a necessary fix for 7.1.

It is interesting that this is the only place in all of our code which
tickles this bug; afaik this line of code appears in other places too.
Can you find a case where the current code fails when you are not doing
arithmetic? Perhaps there are some more tests we could include in the
regression tests??

It is also interesting that afaik AIX is the only machine exhibiting
this problem. The before-1970 range of dates is known to occur in some
use cases, and having *something* in the timezone database isn't that
difficult :/

                       - Thomas

Wed, 10 Jan 2001 14:43:16 +0000
Thomas Lockhart <lockhart@alumni.caltech.edu>
Re: AW: Re: tinterval - operator problems on AIX
Thomas Lockhart writes:
 > > On AIX mktime(3) leaves tm_isdst at -1 if it does not have timezone
 > > info for that particular year and returns -1.
 > > The following code then makes savings time out of the -1.
 > >   tz = (tm->tm_isdst ? (timezone - 3600) : timezone);
 > 
 > Hmm. That description is consistant with what I see in the Linux
 > man page. So I should check for (tm->tm_isdst > 0) rather than
 > checking for non-zero?
 > 
 > Would you like to test that on your machine? I'll try it here, and
 > if successful will consider this a bug report and a necessary fix
 > for 7.1.

I have machines running AIX 4.1.5, 4.2.1, and 4.3.3 if you would like
to send me your test programs.
-- 
Pete Forman                 -./\.- Disclaimer: This post is originated
WesternGeco                   -./\.-  by myself and does not represent
pete.forman@westerngeco.com     -./\.-  opinion of Schlumberger, Baker
http://www.crosswinds.net/~petef  -./\.-  Hughes or their divisions.

Wed, 10 Jan 2001 15:45:38 +0000
Pete Forman <pete.forman@westerngeco.com>
Re: AW: Re: tinterval - operator problems on AIX
> I have machines running AIX 4.1.5, 4.2.1, and 4.3.3 if you would like
> to send me your test programs.

I haven't yet actually fixed the code, but will post patches when I've
done so (assuming that a fix is possible).

                    - Thomas

Thu, 11 Jan 2001 16:52:03 +0000
Thomas Lockhart <lockhart@alumni.caltech.edu>
Re: AW: Re: tinterval - operator problems on AIX
Thomas Lockhart writes:
 > I haven't yet actually fixed the code, but will post patches when
 > I've done so (assuming that a fix is possible).

The normalization in this example program which subtracts 34 years
seems to work OK.  I've run it on AIX, IRIX, Linux and Solaris.  Some
examples follow.

AIX:
$ TZ=PST8PDT ago34 851995921
Local Mon Dec 30 17:32:01 1996 PST PST
      1996-12-30T17:32:01, wday=1, yday=364, isdst = 0
  UTC Tue Dec 31 01:32:01 1996 PST PST
      1996-12-31T01:32:01, wday=2, yday=365, isdst = 0
Local Sun Dec 30 17:32:01 1962 PST PST
      1962-12-30T17:32:01, wday=0, yday=363, isdst = 0
  UTC Mon Dec 31 01:32:01 1962 PST PST
      1962-12-31T01:32:01, wday=1, yday=364, isdst = 0

Linux:
$ TZ=America/Los_Angeles ago34 426475921
Local Thu Jul 07 18:32:01 1983 PDT -0700
      1983-07-07T18:32:01, wday=4, yday=187, isdst = 1
  UTC Fri Jul 08 01:32:01 1983 GMT +0000
      1983-07-08T01:32:01, wday=5, yday=188, isdst = 0
Local Thu Jul 07 18:32:01 1949 PST -0800
      1949-07-07T18:32:01, wday=4, yday=187, isdst = 0
  UTC Fri Jul 08 02:32:01 1949 GMT +0000
      1949-07-08T02:32:01, wday=5, yday=188, isdst = 0

Here is the program.  The call to localtime(&t_ago) is redundant and
hence the adjustment of t_ago can be skipped.  It is in this program
as a sanity check.

As it stands, this program assumes that the input and resulting date
are in the usual UNIX range of [1901, 2038].  I presume that there is
code in place that checks the range of dates.





-- 
Pete Forman                 -./\.- Disclaimer: This post is originated
WesternGeco                   -./\.-  by myself and does not represent
pete.forman@westerngeco.com     -./\.-  opinion of Schlumberger, Baker
http://www.crosswinds.net/~petef  -./\.-  Hughes or their divisions.
Fri, 12 Jan 2001 09:03:40 +0000
Pete Forman <pete.forman@westerngeco.com>
Re: AW: Re: tinterval - operator problems on AIX
> Here is the program.  The call to localtime(&t_ago) is redundant and
> hence the adjustment of t_ago can be skipped.  It is in this program
> as a sanity check.
> As it stands, this program assumes that the input and resulting date
> are in the usual UNIX range of [1901, 2038].  I presume that there is
> code in place that checks the range of dates.

Interesting idea. I'm not sure that assuming that timezones from 1943
are the same as timezones from 2013 (they are not, at least in the US)
is any more valid than just accepting the result from your system. I'd
like to explore more possibilities before we settle on a solution.

Perhaps I should just add checks to assume an unspecified time zone wrt
output formatting if the tm_isdst flag comes back as "-1"?

I'll have to look at the ramifications for input times and for
dump/restore operations. Does you system respect the TZ or PGTZ
environment variable?

                         - Thomas

Fri, 12 Jan 2001 14:54:57 +0000
Thomas Lockhart <lockhart@alumni.caltech.edu>
Re: AW: Re: tinterval - operator problems on AIX
Thomas Lockhart writes:
 > > Here is the program.  The call to localtime(&t_ago) is redundant
 > > and hence the adjustment of t_ago can be skipped.  It is in this
 > > program as a sanity check.
 > > As it stands, this program assumes that the input and resulting
 > > date are in the usual UNIX range of [1901, 2038].  I presume that
 > > there is code in place that checks the range of dates.
 > 
 > Interesting idea. I'm not sure that assuming that timezones from
 > 1943 are the same as timezones from 2013 (they are not, at least in
 > the US) is any more valid than just accepting the result from your
 > system. I'd like to explore more possibilities before we settle on
 > a solution.

As far as AIX and IRIX are concerned the timezones _are_ the same.  No
variation of rules from year to year is possible.  You are not going
to work out DST rules for earlier years without incorporating third
party libraries.  As I understand it PostgreSQL undertakes to
calculate dates only as accurately as the underlying OS allows.

The result of mktime for year < 1970 is always -1 and the struct tm is
not normalized; tm_isdst, tm_wday and tm_yday are not calculated.  I
can't see that being a useful result.

 > Perhaps I should just add checks to assume an unspecified time zone
 > wrt output formatting if the tm_isdst flag comes back as "-1"?

I'm letting the system functions worry about applying time zone and
DST offsets.  At no point do I use tm_isdst, except to set it to and
test it for -1.

Thinking about that a bit more, I think that tm_isdst should not be
written into.  It would be better to set, say, tm_wday to -1 and
change the test for failure to (t_ago == -1 && local.tm_wday == -1).
tm_isdst should be left as 0 or 1 to help out around the times of
transition to or from DST.

 > I'll have to look at the ramifications for input times and for
 > dump/restore operations. Does you system respect the TZ or PGTZ
 > environment variable?

My code uses localtime and mktime which depend on TZ.  There is no
dependency on PGTZ, unless somewhere else in postgres there is an
equivalent of setenv(TZ=getenv(PGTZ)).
-- 
Pete Forman                 -./\.- Disclaimer: This post is originated
WesternGeco                   -./\.-  by myself and does not represent
pete.forman@westerngeco.com     -./\.-  opinion of Schlumberger, Baker
http://www.crosswinds.net/~petef  -./\.-  Hughes or their divisions.

Fri, 12 Jan 2001 15:37:46 +0000
Pete Forman <pete.forman@westerngeco.com>
Re: AW: Re: tinterval - operator problems on AIX
Pete Forman <pete.forman@westerngeco.com> writes:
> Thinking about that a bit more, I think that tm_isdst should not be
> written into.

IIRC, setting isdst to -1 was necessary to get the right behavior across
DST boundaries on more-mainstream systems.  I do not think it's
acceptable to do worse on systems with good time libraries in order to
improve behavior on fundamentally broken ones.

			regards, tom lane

Fri, 12 Jan 2001 10:48:09 -0500
Tom Lane <tgl@sss.pgh.pa.us>
Re: AW: Re: tinterval - operator problems on AIX 
> As far as AIX and IRIX are concerned the timezones _are_ the same.  No
> variation of rules from year to year is possible.  You are not going
> to work out DST rules for earlier years without incorporating third
> party libraries.  As I understand it PostgreSQL undertakes to
> calculate dates only as accurately as the underlying OS allows.

Yes. Hence my reluctance to have code which does time-shifting to get
time zones for all platforms. Perhaps it could/should be a configure
test? And then we can have a "HAVE_SIMPLISTIC_TZ" (or whatever) #define
in the code to enable hacks around the problem? 

The concern led to my suggestion that we should omit timezone fields
from output -- basically do the equivalent of pre-1901 handling using
GMT -- if DST is not resolved correctly (but I'm still not sure if this
will pan out).

>  > I'll have to look at the ramifications for input times and for
>  > dump/restore operations. Does you system respect the TZ or PGTZ
>  > environment variable?
> My code uses localtime and mktime which depend on TZ.  There is no
> dependency on PGTZ, unless somewhere else in postgres there is an
> equivalent of setenv(TZ=getenv(PGTZ)).

Yes there is.

                   - Thomas

Fri, 12 Jan 2001 15:54:43 +0000
Thomas Lockhart <lockhart@alumni.caltech.edu>
Re: AW: Re: tinterval - operator problems on AIX
Tom Lane writes:
 > Pete Forman <pete.forman@westerngeco.com> writes:
 > > Thinking about that a bit more, I think that tm_isdst should not
 > > be written into.
 > 
 > IIRC, setting isdst to -1 was necessary to get the right behavior
 > across DST boundaries on more-mainstream systems.  I do not think
 > it's acceptable to do worse on systems with good time libraries in
 > order to improve behavior on fundamentally broken ones.

A footnote in the C89 (and C99) standard says:

    Thus, a positive or zero value for  tm_isdst  causes  the
    mktime function to presume initially that Daylight Saving
    Time, respectively, is  or  is  not  in  effect  for  the
    specified time.  A negative value causes it to attempt to
    determine whether Daylight Saving Time is in  effect  for
    the specified time.

So tm_isdst being input as 0 or 1 is not forcing the choice of what it
will be on output.  It can be important at the end of DST when local
times repeat and the only way to distinguish them is the setting of
this flag.

That is borne out by my observations.

Setting tm_isdst to -1 before calling mktime can make a difference to
the result when the input and result have different DST flags.

It is fairly arbitrary what the answer to this question is: if six
months is subtracted from a to give b, should a.local.hour =
b.local.hour or should a.utc.hour = b.utc.hour?  If you want the
former then set tm_isdst = -1 before calling mktime.  I'm out of time
now but I'll try and look for some guidance in the SQL standards.
-- 
Pete Forman                 -./\.- Disclaimer: This post is originated
WesternGeco                   -./\.-  by myself and does not represent
pete.forman@westerngeco.com     -./\.-  opinion of Schlumberger, Baker
http://www.crosswinds.net/~petef  -./\.-  Hughes or their divisions.

Fri, 12 Jan 2001 16:14:04 +0000
Pete Forman <pete.forman@westerngeco.com>
Re: AW: Re: tinterval - operator problems on AIX 
Pete Forman <pete.forman@westerngeco.com> writes:
> It is fairly arbitrary what the answer to this question is: if six
> months is subtracted from a to give b, should a.local.hour =
> b.local.hour or should a.utc.hour = b.utc.hour?  If you want the
> former then set tm_isdst = -1 before calling mktime.

It's not arbitrary: we want the former.  Anything else generates
bug reports from people who expect "9/1/2000 - six months" to
produce "3/1/2000", not sometime late in the evening of 2/29/2000.

			regards, tom lane

Fri, 12 Jan 2001 12:34:51 -0500
Tom Lane <tgl@sss.pgh.pa.us>
Re: AW: Re: tinterval - operator problems on AIX 