#!/usr/pkg/bin/perl
# Package for date handling
# Use the PERL std package Time::Local
use Time::Local;

package DATE;
#               J   F   M   A   M   J   J   A   S   O   N   D
@daysinmonth = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
# Find timezone (now) by comparing gmtime to localtime
# for a fixed time that is not on a month boundary
$sometime = 150000;
@gmtime = gmtime($sometime);
@localtime = localtime($sometime);
$timezone = $localtime[2]  - $gmtime[2];
# Day changes.
if ($localtime[3] == $gmtime[3]) {
   # do nothing
} elsif ($localtime[3] == $gmtime[3] + 1) {
   $timezone += 24;
} elsif ($localtime[3] == $gmtime[3] - 1) {
   $timezone -= 24;
} else {
   $gm = join(":", @gmtime);
   $lt = join(":", @localtime);
   die "Problems with timezone: comparing $gm to $lt\n";
}



sub leapyear {
   local($y) = @_;
   local($leap4, $leap100, $leapyear);
   $leap4 = $y / 4;
   $leap100 = $y / 100;
   if (int($leap4) == $leap4 && int($leap100) != $leap100) {
      $leapyear = 1;
   }
   $leapyear;
}

sub weekno {
# Given a time_tm, return week number
   local($tm) = @_;
   local($year, $weekno, $dummy);
   ($dummy, $dummy, $dummy,
    $dummy, $dummy, $year,
    $dummy, $yday, $dummy) = localtime($tm);
   $weekno = int(($yday - &firstdayfirstweek($year) + 7) / 7);
   $weekno;
}


sub firstdayfirstweek {
# Return the day of the year (0 is Jan 1st)
# for the first day of week 1 of any year.
#
# Quoting strftime(3):
#  %V    is replaced by the week number of the year (Monday as the first day
#        of the week) as a decimal number [01,53]. According to ISO 8601 the
#        week containing January 1 is week 1 if it has four or more days in
#        the new year, otherwise it is week 53 of the previous year, and the
#        next week is week 1.  The year is given by the `%G' conversion
#        specification.
#
# So this will return a negative value in some cases, i.e. when
# Jan 1st falls on either of Tuesday, Wednesday or Thursday, and
# will be positive (1) or zero for Sunday or Monday respectively.
#
   local($y) = @_;
   local($ret);
   # Get time of January 1, 0.0.0.0
   # Note that DST is never in effect on Jan 1...
   local($firsttime) = &main::timelocal(0, 0, 0, 1, 0, $y, 0, 0, 0);
   local(@firstday) = localtime($firsttime);
   local($wday) = $firstday[6];
   # Weekday 4 is Thursday (localtime returns zero-based with Sunday = 0)
   if ($wday <= 4) {
       $ret = 1 - $wday;	# first day of week 1 may be in late December
       				# The exception is when Jan 1 = Sunday (wday 0)
   } else {
       $ret = 8 - $wday;	# first day of week 1 is in January
   }
   return $ret;
}
 
sub firstinweek {
# Return timevalue for 2 hours into the day
# (to avoid DST troubles)
   local($weekno, $year) = @_;
   # 2 hours into this year
   local($time) = &main::timelocal(0, 0, 2, 1, 0, $year, 0, 0, 0);
   # Add number of days since start of year
   $time += (($weekno - 1) * 7 + &firstdayfirstweek($year)) * 60 * 60 * 24;
   $time;
}

1; # Everything is fine
