From: pruy@nessy.informatik.uni-erlangen.de (Rainer Pruy)
Subject: Re: help with timelocal.pl
Organization: CSD., University of Erlangen
Date: Mon, 17 Aug 1992 16:14:21 GMT

In <1992Aug14.190949.10466@rock.concert.net> cole@concert.net (Derrick C. Cole) writes:

> Greetings, again!
> Does anyone have a good subroutine for computing the difference in seconds
> between two time stamps?  I'm trying to use timelocal() in mine, but it never
> returns:
> require "/usr/local/lib/perl/timelocal.pl";
> chop($year = `date +\"\%y\"`);
> [perl code deleted]
> I'm doing something wrong, but can't figure out what it is (don't use packages
> very often, if that's it...)  Can anyone improve upon/fix this subroutine?

No, not you are doing something wrong, there is a bug in timelocal.pl.

gmlocal() and timelocal() will fail for any date before (19)70
due to a bug in &timelocal'cheat.

My version of cheat looked like:

:00:sub cheat {
:01:    $year = $_[5];
:02:    $month = $_[4];
:03:    $guess = $^T;
:04:    @g = gmtime($guess);
:05:    while ($diff = $year - $g[5]) {
:06:        $guess += $diff * (364 * $DAYS);
:07:        @g = gmtime($guess);
:08:    }
:09:    while ($diff = $month - $g[4]) {
:10:        $guess += $diff * (28 * $DAYS);
:11:        @g = gmtime($guess);
:12:    }
:13:    $g[3]--;
:14:    $guess -= $g[0] * $SEC + $g[1] * $MIN + $g[2] * $HR + $g[3] * $DAYS;
:15:    $cheat{$ym} = $guess;
:16:}

This bug shows up as soon as your system interpretes dates 0-69 to be 2000-2069
while cheat assumes them to be 1900-1969.

On my SS2 (SunOS 4.1.2) the loop at line 05 gets stuck at a difference of 1 year.

I fixed it the following way:

*** timelocal.pl.orig	Mon Aug 17 17:56:09 1992
--- timelocal.pl	Thu Jul  2 23:47:42 1992
***************
*** 35,40 ****
--- 35,41 ----
      $MIN = 60 * $SEC;
      $HR = 60 * $MIN;
      $DAYS = 24 * $HR;
+     $YearFix = ((gmtime(946684800))[5] == 100) ? 100 : 0;
  }
  
  sub timegm {
***************
*** 61,67 ****
--- 62,69 ----
      $month = $_[4];
      $guess = $^T;
      @g = gmtime($guess);
+     $year += $YearFix if $year < $epoch[5];
      while ($diff = $year - $g[5]) {
        $guess += $diff * (364 * $DAYS);
        @g = gmtime($guess);
      }

line 38 (Hunk 1) determines whether &chat and gmtime() dissagree on year
interpretation and line 64 (Hunk 2) fixes the representation given.

> Any and all help greatly appreciated!
> Derrick Cole

Hope this fixes your problem..

Rainer Pruy

 /----------------------------------------------------------------------------\
 | Rainer Pruy           | email:                                             |
 |                       |  DOMAIN: pruy@informatik.uni-erlangen.de           |
 | Friedrich-Alexander   |  X400:   /C=de/A=dbp/P=uni-erlangen/OU=informatik/ |
 | Universitaet          |          /S=Pruy/G=Rainer/                         |
 |                       |  UUCP:   ...!uunet!fauern!pruy                     |
 | CS Department IMMD IV |----------------------------------------------------|
 | (operating systems)   | phone:  +49 9131 85-7909                           |
 |                       |----------------------------------------------------|
 | Martensstrasse 1      | ================================================== |
 |                       |//   Programming Department:                      \\|
 | D-8520 Erlangen       |\\           Mistakes made while you wait         //|
 | Germany               | ================================================== |
 \----------------------------------------------------------------------------/