Обсуждение: AW: AW: Re: tinterval - operator problems on AIX

Поиск
Список
Период
Сортировка

AW: AW: Re: tinterval - operator problems on AIX

От
Zeugswetter Andreas SB
Дата:
> > 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?

It is obviously not possible to determine tm_isdst with mktime for a 
negative time_t. Thus with above fix PST works, but PDT is then busted :-(
localtime does convert a negative time_t correctly including dst.
Is there another way to determine tm_isdst ?

Andreas


Re: AW: AW: Re: tinterval - operator problems on AIX

От
Thomas Lockhart
Дата:
> > > 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?
> It is obviously not possible to determine tm_isdst with mktime for a
> negative time_t. Thus with above fix PST works, but PDT is then busted :-(

Obvious to AIX only? My conclusion is that the AIX timezone database is
damaged or missing for pre-1970 dates, but that other systems bothered
to get it at least somewhat right. Is there another issue here that I'm
missing?

> localtime does convert a negative time_t correctly including dst.
> Is there another way to determine tm_isdst ?

Yes. Replace AIX with Linux or something else, then recompile Postgres
;)

Seriously, not that I know of. The problem is that there is no API for
accessing time zone info other than the localtime()/mktime() kinds of
calls, so we are stuck using that (or stuck repackaging something like
zinc into Postgres directly, which afaik is not anything we would be
interested in doing).
                     - Thomas


Re: AW: AW: Re: tinterval - operator problems on AIX

От
Pete Forman
Дата:
Zeugswetter Andreas SB writes:> Try the attachment with negative values, and tell us whether mktime> returns anything
otherthat -1. Do you have an idea how else we> could determine daylight savings time ?
 

mktime always returns -1 for tm's that might expect to return a
negative number.  In those cases the tm is not normalized and
tm_isdst is set to -1.  When mktime returns zero or positive then tm
is normalized and tm_isdst is set to 0 or 1.

localtime sets all the fields of tm correctly, including tm_isdst, for
all values of time_t, including negative ones.  When I say correctly,
there is the usual limitation that the rules to specify when DST is in
force cannot express a variation from year to year.  (You can specify
e.g. the last Sunday in a month.)

My observations were consistent across AIX 4.1.5, 4.2.1, and 4.3.3.


If you have a time_t, then you can use localtime to determine DST.  If
you have a tm then you cannot work out DST for dates before the epoch.
One workaround would be to add 4*n to tm_year and subtract (365*4+1)
*24*60*60*n from the time_t returned.  (All leap years are multiples
of 4 in the range 1901 to 2038.  If tm_wday is wanted, that will need
to be adjusted as well.)  But don't you do time interval arithmetic
using PostgreSQL date types rather than accepting the limitations of
POSIX/UNIX?
-- 
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.


Re: AW: AW: Re: tinterval - operator problems on AIX

От
Pete Forman
Дата:
Pete Forman writes:> One workaround would be to add 4*n to tm_year and subtract (365*4+1)> *24*60*60*n from the time_t
returned. (All leap years are multiples> of 4 in the range 1901 to 2038.  If tm_wday is wanted, that will need> to be
adjustedas well.)
 

FWIW, that should be to add 28*n to tm_year and subtract (365*4+1)*7
*24*60*60*n from the time_t returned.  That calculates tm_wday
correctly.

Also I should have been more explicit that this applies only to AIX
and IRIX.  Those return -1 from mktime(year < 1970) and do not allow
DST rules to vary from year to year.  Linux and Solaris have more
capable date libraries.
-- 
Pete Forman   http://www.bedford.waii.com/wsdev/petef/PeteF_links.html
WesternGeco                           http://www.crosswinds.net/~petef
Manton Lane, Bedford,               mailto:pete.forman@westerngeco.com
MK41 7PA, UK                  tel:+44-1234-224798  fax:+44-1234-224804


Re: AW: AW: Re: tinterval - operator problems on AIX

От
Thomas Lockhart
Дата:
> FWIW, that should be to add 28*n to tm_year and subtract (365*4+1)*7
> *24*60*60*n from the time_t returned.  That calculates tm_wday
> correctly.
> Also I should have been more explicit that this applies only to AIX
> and IRIX.  Those return -1 from mktime(year < 1970) and do not allow
> DST rules to vary from year to year.  Linux and Solaris have more
> capable date libraries.

Oh, so AIX and IRIX have just one-line time zone databases? Yuck.

How about having some #if BROKEN_TIMEZONE_DATABASE code which uses both
mktime() and localtime() to derive the correct time zone? That is, call
mktime to get a time_t, then call localtime() to get the time zone info,
but only on platforms which do not get a complete result from just the
call to mktime(). In fact, we *could* check for tm->tm_isdst coming back
"-1" for every platform, then call localtime() to make a last stab at
getting a good value.

Comments?
                       - Thomas