develooper Front page | perl.perl5.porters | Postings from January 2012

Re: POSIX::strftime fails to cope with negative mday

Thread Previous
From:
Paul LeoNerd Evans
Date:
January 28, 2012 08:10
Subject:
Re: POSIX::strftime fails to cope with negative mday
Message ID:
20120128161024.GH8369@cel.leo
On Wed, Jan 25, 2012 at 05:06:46PM +0000, Paul LeoNerd Evans wrote:
> On Tue, Jan 24, 2012 at 11:13:38AM +0000, Paul LeoNerd Evans wrote:
> > I can see no reason why one ought to work when the other does not, given
> > as POSIX::strftime is supposed to be normalising values, and it does
> > when they are positive. I suspect a signed/unsigned bug somewhere.
> 
> Well, since nobody seems to express an opinion, I'm going to have a
> quick look and see if I can see an obvious bug and send a patch. If not
> I wonder if it would be best to document that POSIX::strftime() will not
> work with non-normalised values, and possibly even remove the call to
> mini_mktime() within it.

Actually this is now looking weirder.

Today is:

 $ perl5.12.4 -MPOSIX=strftime -E 'say strftime "%Y/%m/%d", localtime'
 2012/01/28

Can't do 30 days ago, because this breaks:

 $ perl5.12.4 -MPOSIX=strftime -E 'my @t = localtime; $t[3] -= 30; say strftime "%Y/%m/%d", @t'
 2012/01/28

But, -can- do 30 days ago this way:

 $ perl5.12.4 -MPOSIX=strftime -E 'my @t = localtime; say strftime "%Y/%m/%d", @t[0..2], $t[3]-30, @t[4..5]'
 2011/12/29

The only difference I can find is the number of elements passed into
strftime; the latter passes just the 6 primary ones, the former passes
all 9. So I tried playing around with it:

 $ perl5.12.4 -MPOSIX=strftime -E 'my @t = localtime; $t[3] -= 30; say strftime "%Y/%m/%d", @t[0..5]'
 2011/12/29

 $ perl5.12.4 -MPOSIX=strftime -E 'my @t = localtime; $t[3] -= 30; say strftime "%Y/%m/%d", @t[0..6]'
 2011/12/29

 $ perl5.12.4 -MPOSIX=strftime -E 'my @t = localtime; $t[3] -= 30; say strftime "%Y/%m/%d", @t[0..7]'
 2012/01/28

So it appears that if POSIX::strftime() thinks it has to recalculate the
[7] element, tm_yday, then it gets it correct, whereas if it doesn't
then it just reuses that for "normalising" the tm_mday field. A
plausible theory:

 $ perl5.12.4 -MPOSIX=strftime -E 'my @t = localtime; $t[3] -= 30; $t[7] -= 30; say strftime "%Y/%m/%d", @t'
 2011/12/29

But why, preytell, only do that if $t[3] is negative, and not positive.
I note you can do 30 days hence a much simpler:

 $ perl5.12.4 -MPOSIX=strftime -E 'my @t = localtime; $t[3] += 30; $t[7] += 30; say strftime "%Y/%m/%d", @t'
 2012/02/27

 $ perl5.12.4 -MPOSIX=strftime -E 'my @t = localtime; $t[3] += 30; say strftime "%Y/%m/%d", @t'
 2012/02/27

So it's still inconsistent, just even weirder.

-- 
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk
ICQ# 4135350       |  Registered Linux# 179460
http://www.leonerd.org.uk/

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About