Ticket #505 (new todo)

Opened 6 years ago

Last modified 4 years ago

avoid 2038 bug

Reported by: coke Owned by:
Priority: minor Milestone:
Component: core Version:
Severity: medium Keywords:
Cc: particle, dukeleto Language:
Patch status: Platform: all

Description

Original reported here:  http://rt.perl.org/rt3/Ticket/Display.html?id=57728

>> we definitely need date/time pmc(s?) not only to have a common epoch
>> across platforms, but to deal with 2038. in particular, we should
>> leverage schwern's work on perl to address the 2038 bug.
>> ~jerry
>
> We definitely haven't already fixed this. Here's an easy test using
> libfaketime:
>
> $ cat time.pir
> .sub main :main
> .local int time_int
> time time_int
> say time_int
> .end
> $ ./parrot time.pir
> 1222213121
> $ LD_PRELOAD=/usr/src/libfaketime-0.8/libfaketime.so.1 FAKETIME="+40y"
> ./parrot time.pir
> -1811314167

We can't make this example work. If you use an INTVAL, and the INTVAL
can be signed 32 bits, there is no way to have a more than 31 bits
unsigned stored on it as such.

-- 
Salu2

Since this is unlikely to get resolved shortly and only has a small amount of history, moving tracking of issue here.

Change History

  Changed 4 years ago by jkeenan

  • component changed from none to core

Is there someone who could investigate the work done by Schwern in Perl 5 on the 2038 problem and prepare a report on it for Parrot developers?

Thank you very much.

kid51

  Changed 4 years ago by dukeleto

Using these headers:

 https://github.com/schwern/y2038

looks like the simplest way to do this. From what I remember hearing from Schwern, we don't want to reimplement that stuff.

follow-up: ↓ 6   Changed 4 years ago by schwern

You don't want to reimplement that stuff. :-)

Executive Summary: In the short run, y2038 will give you a working, portable post-2038 time.h on which to base your times and dates. In the long run you're probably better off shipping your own zone file and implementing your own time library. And Parrot is nothing if not in the long run.

tl;dir version follows.

You have two approaches to dealing with time zones. They hinge on one thing: do you want to ship your own time zone files?

If yes, then do that and ignore the time.h local time stuff. It sucks. The implementations suck. The interface sucks and you don't have to be compatible with it. Do it yourself and give it a better interface. The down side is having redundant zone files in Parrot and the system. This means if there's a change to the TZ rules, Parrot might work differently than other systems. You can mitigate this by having Parrot be configurable to use the system zone files, if it can find them and if they're sane, and falling back to its own. It also allows vendors to configure Parrot to use their known good zone files. If you choose to go down that route, Zefram is the one to talk to and there's a number of great time libraries out there to base that work on.

(There is a side issue that the system time zone files might not be 2038 clean. This is something that can be tested for and you can fall back.)

If you don't want to ship zone files, then the only universal interface to system time zone information is localtime() and mktime() and those are not guaranteed to be 32 bit safe. You can use y2038 to hack around this, and it works (Perl 5 is using it in production) but this you're always going to risk local time after 2038 and before 1970 being off by an hour or two. It also involves some complicated probing to determine the capabilities of the system time.h.

Finally, in my experience "64 bit" time.h implementations can only be universally trusted out to 47 bits. After that there's bugs, some of them ugly... like gmtime() or localtime() just hangs. Or OS X's gmtime() just loses a day somewhere. Or time_t's year is limited to 32 bits (ie. 2 billion years) which y2038 can work around, but it's ugly. Fortunately 47 bits gives you 4.4 million years which is more than enough. Anyone who needs more (astronomers & archeologists) don't care about time zones and do things in Julian days anyway.

  Changed 4 years ago by dukeleto

  • cc dukeleto added
  • platform set to all

in reply to: ↑ 4   Changed 4 years ago by theory

Replying to schwern:

Executive Summary: In the short run, y2038 will give you a working, portable post-2038 time.h on which to base your times and dates. In the long run you're probably better off shipping your own zone file and implementing your own time library. And Parrot is nothing if not in the long run.

FWIW, PostgreSQL ships with its own zone files. This means that the core developers have to update them periodically, but it doesn't seem to be a big deal. And Parrot's time-based release schedule ensures that there will always be timely release of updated zone files.

The fact that PostgreSQL ships its own zone files is a huge advantage, IMHO, because then the behavior is universal across platforms (and vendors are often slow to update zone files). It's just a huge headache that I don't have to think about.

So I'd like to just +1 Schwern's suggestion that Parrot ship with time zone files as likely the best way to deal with the whole issue.

Note: See TracTickets for help on using tickets.