Subject: Re: mktime(3) fails to convert a time in the "spring forward gap"
To: NetBSD Userlevel Technical Discussion List <tech-userlevel@NetBSD.ORG>
From: Greg A. Woods <woods@weird.com>
List: tech-userlevel
Date: 10/10/2002 01:09:20
[ On Wednesday, October 9, 2002 at 16:17:37 (-0700), Bill Studenmund wrote: ]
> Subject: Re: mktime(3) fails to convert a time in the "spring forward gap" 
>
> On Wed, 9 Oct 2002, Greg A. Woods wrote:
> > 
> > Of course that patch is against Eggert's implementation in GNU Libc....
> 
> From reading the URL you posted, he seemed to be going along with what
> other implementations were doing too, which isn't necessarily right.

Yes, and I should follow up on that because I had thought there were
very few other modern implementations independent from the same tzcode
distribution used in NetBSD et al.

> > > How does this patch deal with the cases of both taking 0130 and adding an
> > > hour, and taking 0330 and subtracting an hour? If I understand what it'll
> > > do, it will be ok for 0130 + an hour, but get 0330 - an hour wrong.
> >
> > But that's not "an hour wrong".  That's exactly what ctime(&time(NULL))
> > will return in one hour from that 01:30 local time since there is no
> > 02:30 for the presumed timezone on the day of the gap.
> 
> You mis-parsed that. It wasn't "get 0330" which is an hour wrong, but get
> "0330 MINUS one hour" (0130) wrong, since it'll actually give back 0330.

Ah, OK, yes, I see what you mean.  I can't really offer any better ideas
myself though, at least not without intimate knowlege of the current DST
rules....

> i.e. this works fine for adding times to a struct tm, but not for
> subtracting.

yes, depending on where you start from of course!  :-)

> Sounds like what we need is tmadd(struct tm *atime, struct tm *delta),
> where you have a struct tm and you pass in an explicit delta. *atime gets
> updated as per delta.
> 
> You set all fields in *delta to zero other than the one(s) you want to
> change. You set the latter to the amounts you want to adjust. Thus to add
> an hour to a date, you set tm_hour = 1. To subtract a month, you instead
> set tm_mon = -1.

Yes, that's sort of the kind of thing I've conjured up myself (using
mktime() internally) when I've done these kinds of things in the past
(though never quite so flexible I don't think), but if there were a way
to do it while being cognizant of the DST rules for the current timezone
then perhaps the various incongruencies you've pointed out might be
avoided.  It might be quite a job getting such an API into common enough
use though that we could actually avoid "fixing" mktime() ala Paul
Eggert's fix.

-- 
								Greg A. Woods

+1 416 218-0098;            <g.a.woods@ieee.org>;           <woods@robohack.ca>
Planix, Inc. <woods@planix.com>; VE3TCP; Secrets of the Weird <woods@weird.com>