source: trunk/third/xntp/scripts/monitoring/timelocal.pl @ 10832

Revision 10832, 2.5 KB checked in by brlewis, 27 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r10831, which included commits to RCS files with non-trunk default branches.
  • Property svn:executable set to *
Line 
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
24CONFIG: {
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
41sub 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
49sub 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
58package timelocal;
59
60sub 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}
Note: See TracBrowser for help on using the repository browser.