Annotation of embedaddon/ntp/scripts/monitoring/timelocal.pl, revision 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>