Annotation of embedaddon/ntp/scripts/monitoring/timelocal.pl, revision 1.1.1.1

1.1       misho       1: ;# timelocal.pl
                      2: ;#
                      3: ;# Usage:
                      4: ;#     $time = timelocal($sec,$min,$hours,$mday,$mon,$year,$junk,$junk,$isdst);
                      5: ;#     $time = timegm($sec,$min,$hours,$mday,$mon,$year);
                      6: 
                      7: ;# These routines are quite efficient and yet are always guaranteed to agree
                      8: ;# with localtime() and gmtime().  We manage this by caching the start times
                      9: ;# of any months we've seen before.  If we know the start time of the month,
                     10: ;# we can always calculate any time within the month.  The start times
                     11: ;# themselves are guessed by successive approximation starting at the
                     12: ;# current time, since most dates seen in practice are close to the
                     13: ;# current date.  Unlike algorithms that do a binary search (calling gmtime
                     14: ;# once for each bit of the time value, resulting in 32 calls), this algorithm
                     15: ;# calls it at most 6 times, and usually only once or twice.  If you hit
                     16: ;# the month cache, of course, it doesn't call it at all.
                     17: 
                     18: ;# timelocal is implemented using the same cache.  We just assume that we're
                     19: ;# translating a GMT time, and then fudge it when we're done for the timezone
                     20: ;# and daylight savings arguments.  The timezone is determined by examining
                     21: ;# the result of localtime(0) when the package is initialized.  The daylight
                     22: ;# savings offset is currently assumed to be one hour.
                     23: 
                     24: CONFIG: {
                     25:     package timelocal;
                     26:     
                     27:     @epoch = localtime(0);
                     28:     $tzmin = $epoch[2] * 60 + $epoch[1];       # minutes east of GMT
                     29:     if ($tzmin > 0) {
                     30:        $tzmin = 24 * 60 - $tzmin;              # minutes west of GMT
                     31:        $tzmin -= 24 * 60 if $epoch[5] == 70;   # account for the date line
                     32:     }
                     33: 
                     34:     $SEC = 1;
                     35:     $MIN = 60 * $SEC;
                     36:     $HR = 60 * $MIN;
                     37:     $DAYS = 24 * $HR;
                     38:     $YearFix = ((gmtime(946684800))[5] == 100) ? 100 : 0;
                     39: }
                     40: 
                     41: sub timegm {
                     42:     package timelocal;
                     43: 
                     44:     $ym = pack(C2, @_[5,4]);
                     45:     $cheat = $cheat{$ym} || &cheat;
                     46:     $cheat + $_[0] * $SEC + $_[1] * $MIN + $_[2] * $HR + ($_[3]-1) * $DAYS;
                     47: }
                     48: 
                     49: sub timelocal {
                     50:     package timelocal;
                     51: 
                     52:     $ym = pack(C2, @_[5,4]);
                     53:     $cheat = $cheat{$ym} || &cheat;
                     54:     $cheat + $_[0] * $SEC + $_[1] * $MIN + $_[2] * $HR + ($_[3]-1) * $DAYS
                     55:        + $tzmin * $MIN - 60 * 60 * ($_[8] != 0);
                     56: }
                     57: 
                     58: package timelocal;
                     59: 
                     60: sub cheat {
                     61:     $year = $_[5];
                     62:     $month = $_[4];
                     63:     $guess = $^T;
                     64:     @g = gmtime($guess);
                     65:     $year += $YearFix if $year < $epoch[5];
                     66:     while ($diff = $year - $g[5]) {
                     67:        $guess += $diff * (364 * $DAYS);
                     68:        @g = gmtime($guess);
                     69:     }
                     70:     while ($diff = $month - $g[4]) {
                     71:        $guess += $diff * (28 * $DAYS);
                     72:        @g = gmtime($guess);
                     73:     }
                     74:     $g[3]--;
                     75:     $guess -= $g[0] * $SEC + $g[1] * $MIN + $g[2] * $HR + $g[3] * $DAYS;
                     76:     $cheat{$ym} = $guess;
                     77: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>