--- Available.pm 2003/10/03 16:40:00 1.3 +++ Available.pm 2003/10/05 22:26:54 1.6 @@ -63,6 +63,7 @@ # calc start and stop seconds my (\$hh,\$mm,\$ss) = split(/:/,\$self->{ARGS}->{start},3); + print STDERR "new: start time ",\$hh||0,":",\$mm||0,":",\$ss||0,"\n" if (\$debug); my \$s = \$hh * 3600 || die("need at least hour specified for start time"); \$s += \$mm * 60 if (\$mm); \$s += \$ss if (\$ss); @@ -71,6 +72,7 @@ die("need end time") if (! \$self->{ARGS}->{end}); (\$hh,\$mm,\$ss) = split(/:/,\$self->{ARGS}->{end},3); + print STDERR "new: end time ",\$hh||0,":",\$mm||0,":",\$ss||0,"\n" if (\$debug); \$s = \$hh * 3600 || die("need at least hour specified for end time"); \$s += \$mm * 60 if (\$mm); \$self->{end} = \$s; @@ -126,25 +128,26 @@ sub uptime { my \$self = shift; - my \$time = shift || die "need uptime timestamp to calcualte uptime"; + my \$time = shift || die "need uptime timestamp to calculate uptime"; # calculate offset -- that is number of seconds since midnight - my @lt = localtime(\$time); + my @lt = gmtime(\$time); + + # check if day falls into dayMask + return 0 if (! \$self->_dayOk(\$lt[6]) ); + my \$offset = \$lt[2]; # hour \$offset *= 60; # convert to minutes \$offset += \$lt[1]; # minutes \$offset *= 60; # convert to seconds \$offset += \$lt[0]; - # check if day falls into dayMask - return 0 if (! \$self->_dayOk(\$lt[6]) ); - my \$s=0; my \$start = \$self->{start}; my \$end = \$self->{end}; - print STDERR "start: \$start end: \$end time: \$offset\n" if (\$debug); + print STDERR "start: \$start end: \$end time: \$offset [\$lt[2]:\$lt[1]:\$lt[0]]\n" if (\$debug); if ( \$end > \$start ) { if (\$offset < \$start) { @@ -172,6 +175,60 @@ } # +# this will return number of seconds that service is available if passed +# downtime of service +# + +sub downtime { + my \$self = shift; + + my \$time = shift || die "need downtime timestamp to calculate uptime"; + + # calculate offset -- that is number of seconds since midnight + my @lt = gmtime(\$time); + + # check if day falls into dayMask + return 0 if (! \$self->_dayOk(\$lt[6]) ); + + my \$offset = \$lt[2]; # hour + \$offset *= 60; # convert to minutes + \$offset += \$lt[1]; # minutes + \$offset *= 60; # convert to seconds + \$offset += \$lt[0]; + + my \$s=0; + + my \$start = \$self->{start}; + my \$end = \$self->{end}; + + print STDERR "start: \$start end: \$end time: \$offset [\$lt[2]:\$lt[1]:\$lt[0]]\n" if (\$debug); + + if ( \$end > \$start ) { + if (\$offset > \$start && \$offset <= \$end) { + \$s = \$end - \$offset; + } elsif (\$offset < \$start) { + \$s = \$end - \$start; + } + } elsif ( \$start > \$end ) { # over midnight + if ( \$offset < \$end ) { + if ( \$offset < \$start) { + \$s = \$offset; + } else { + \$s = 0; + } + } else { + if ( \$offset < \$start ) { + \$s = SEC_PER_DAY - \$end; + } else { + \$s = SEC_PER_DAY - \$end + \$start - \$offset; + } + } + } + + return \$s; +} + +# # this auxillary function will pretty-format interval in [days]d hh:mm:ss # @@ -193,6 +250,79 @@ return \$out; } +# +# this function will calculate uptime for some interval +# + +sub interval { + my \$self = shift; + my \$from = shift || die "need start time for interval"; + my \$to = shift || die "need end time for interval"; + + print STDERR "from:\t\$from\t",scalar gmtime(\$from),"\n" if (\$debug); + print STDERR "to:\t\$to\t",scalar gmtime(\$to),"\n" if (\$debug); + + my \$total = 0; + + # calc first day availability + print STDERR "t:\t\$from\t",scalar gmtime(\$from),"\n" if (\$debug); + \$total += \$self->uptime(\$from); + + print STDERR "total: \$total (first)\n" if (\$debug); + + # add all whole days + + my \$sec_in_day = \$self->sec_in_interval; + my \$day = 86400; # 24*60*60 + + my \$loop_start_time = int(\$from/\$day)*\$day + \$day; + my \$loop_end_time = int(\$to/\$day)*\$day - \$day; + + print STDERR "loop (start - end): \$loop_start_time - \$loop_end_time\n" if (\$debug); + + for (my \$t = \$loop_start_time; \$t <= \$loop_end_time; \$t += \$day) { + print STDERR "t:\t\$t\t",scalar gmtime(\$t),"\n" if (\$debug); + \$total += \$sec_in_day if (\$self->day_in_interval(\$t)); + print STDERR "total: \$total (loop)\n" if (\$debug); + } + + # add rest of last day + print STDERR "t:\t\$to\t",scalar gmtime(\$to),"\n" if (\$debug); + + \$total -= \$self->downtime(\$to); + print STDERR "total: \$total (final)\n" if (\$debug); + + return \$total; +} + +# +# this function will check if day falls into interval +# + +sub day_in_interval { + my \$self = shift; + + my \$time = shift || die "need timestamp to check if day is in interval"; + + my @lt = gmtime(\$time); + return \$self->_dayOk(\$lt[6]); +} + +# +# return seconds in defined interval +# + +sub sec_in_interval { + my \$self = shift; + + # over midnight? + if (\$self->{start} > \$self->{end}) { + return(86400 - \$self->{start} + \$self->{end}); + } else { + return(\$self->{end} - \$self->{start}); + } +} + 1; __END__ @@ -239,34 +369,34 @@ =over 4 =item * -Time::Avail::DAY_MONDAY +Time::Available::DAY_MONDAY =item * -Time::Avail::DAY_TUESDAY +Time::Available::DAY_TUESDAY =item * -Time::Avail::DAY_WEDNESDAY +Time::Available::DAY_WEDNESDAY =item * -Time::Avail::DAY_THURSDAY +Time::Available::DAY_THURSDAY =item * -Time::Avail::DAY_FRIDAY +Time::Available::DAY_FRIDAY =item * -Time::Avail::DAY_SATURDAY +Time::Available::DAY_SATURDAY =item * -Time::Avail::DAY_SUNDAY +Time::Available::DAY_SUNDAY =item * -Time::Avail::DAY_WEEKDAY +Time::Available::DAY_WEEKDAY =item * -Time::Avail::DAY_WEEKEND +Time::Available::DAY_WEEKEND =item * -Time::Avail::DAY_EVERYDAY +Time::Available::DAY_EVERYDAY =back