Mailing List Archive

Giving a negative time to gmtime/localtime -- is this a feature?
Accidentally discovered that if you give localtime/gmtime a negative number it will decode to a date/time prior to 1970. That's a useful trick! This feature seems to be available back to at least 5.10 (when I was a lot more active here). I've either forgotten this feature existed or it passed by without me noticing at the time.

Don't see this documented in the localtime/gmtime pod. May be hidden somewhere else in the docs. Think there should be a mention of it in the localtime/gmtime pod pages even if it just a "see xxx for more details" link.


I stumbled across this when decoding Windows NTFS timestamps and one of the NTFS timestamps happened to have a value of zero. NTFS timestamps are stored as elapsed nano-seconds since 1st Jan 1601. To get something that gmtime/localtime understands you need to convert from nano-second to second precision and subtract 11644473600 from the timestamp. That gives an elapsed seconds value relative to 1st Jan 1970.

Below is the equivalent to what my code runs with the zero NTFS timestamp:


$ perl -e 'print scalar gmtime -11644473600'
Mon Jan 1 00:00:00 1601

That is spot-on! But...

I have a GitHub workflow that works just fine on Linux & Mac from 5.10 up to 5.38 but on Windows I'm seeing different behaviour with 5.10 (5.12 through 5.38 are fine ) - in my application code gmtime/localtime returns undef when I give it the -11644473600 value. The simple command line example above works just fine on Windows 5.10 for some reason. Suspect this may be a PV/IV thing but nothing is jumping out at me.

If there is a known issue with negative time on 5.10, what version is this feature stable at?

Paul
Re: Giving a negative time to gmtime/localtime -- is this a feature? [ In reply to ]
Paul Marquess wrote:
>
> If there is a known issue with negative time on 5.10, what version is this feature stable at?

perl5120delta only mentions the Y2038 fixes. But according to perlport from that era, whether time before 1970 is supported depended on the OS's implementation of "localtime" until v5.10. Since v5.12 it's always supposed to work (with caveats).

https://perldoc.perl.org/5.10.1/perlport#localtime

https://perldoc.perl.org/5.12.0/perlport#gmtime


--
Arne Johannessen
<https://arne.johannessen.de/>