--- innreport	2010-08-01 12:07:53.000000000 +0200
+++ innreport	2012-01-07 00:24:00.000000000 +0100
@@ -95,6 +95,7 @@
 
 use strict;
 use Carp qw( cluck confess );
+use Time::Local;
 
 ## Do you want to create a Web page. Pick DO or DONT.
 my $HTML = "DONT";
@@ -338,34 +339,11 @@
 my @unrecognize;
 my ($total_line, $total_size) = (0, 0);
 my ($suffix, $HTML_output, %config, %prog_type, %prog_size);
-my ( @month_to_dayofyear, %month_to_dayofyear, $current_year );
-
+my $current_year;
 {
   my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
     localtime(time);
   $current_year = $year += 1900;
-  my $isLeapYear =
-   (($year % 4 == 0) && ($year % 100 != 0)) || ($year % 400 == 0);
-
-  @month_to_dayofyear = $isLeapYear
-  ? ( -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 366 )
-  : ( -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 365 );
-
-  %month_to_dayofyear =
-  (
-    'Jan' => $month_to_dayofyear[ 0],
-    'Feb' => $month_to_dayofyear[ 1],
-    'Mar' => $month_to_dayofyear[ 2],
-    'Apr' => $month_to_dayofyear[ 3],
-    'May' => $month_to_dayofyear[ 4],
-    'Jun' => $month_to_dayofyear[ 5],
-    'Jul' => $month_to_dayofyear[ 6],
-    'Aug' => $month_to_dayofyear[ 7],
-    'Sep' => $month_to_dayofyear[ 8],
-    'Oct' => $month_to_dayofyear[ 9],
-    'Nov' => $month_to_dayofyear[10],
-    'Dec' => $month_to_dayofyear[11],
-  );
 }
 
 my $HTML_header = '';
@@ -387,14 +365,13 @@
 # an unsigned integer (either 32 or 64 bit).
 
 my $first_date = undef;    # lowest encountered date
-my $first_date_cvt = 1E30; # = &ConvDate($first_date)
+my $first_date_cvt = 1E30; # = &ConvDate($current_year . ' ' . $first_date)
 my $last_date = undef;     # highest encountered date
-my $last_date_cvt = -1;    # = &ConvDate($last_date)
+my $last_date_cvt = -1;    # = &ConvDate($current_year . ' ' . $last_date)
 
-# $date_wrap_around is a day of year.  If it is positive, then the log
-# file goes past 31st of December into January.  In that case, 365 (or
-# 366) is added to all dates less than $date_wrap_around.
-my $date_wrap_around = $month_to_dayofyear[ 0];
+# If $wrap_around is positive, then the log file goes past 31st of December
+# into January.
+my $wrap_around = 0;
 
 #########################################################################
 if (length($CLASS) == 0)
@@ -468,13 +445,17 @@
       last UNRECOGNIZED;
     } # DECODE
 
+    # Do not add $current_year to $date_str because years are not expected
+    # in $first_date and $last_date when used afterwards.
+    # Take the current year because we assume that we are not re-parsing
+    # an old log file.
     my $date_str = $day . ' ' . $hour;
-    my $cvtdate = &ConvDate ($date_str);
+    my $cvtdate = &ConvDate ($current_year . ' ' . $date_str, $wrap_around);
     last UNRECOGNIZED if (!defined($cvtdate));
 
     if ($cvtdate < $first_date_cvt)
     {
-      if ($first_date_cvt - $cvtdate > 253 * 24 * 60 * 60 && $first_date)
+      if ($first_date_cvt - $cvtdate > 253 * 24 * 60 * 60 && defined($first_date))
       { #
         # Detected excessive distance between log entries (see function
         # DateCompare for magic number 253).  This means we are crossing
@@ -490,13 +471,13 @@
         # belong to current year.  With this definition, it is not possible
         # to cross from both 31st of December to 1st of January and from
         # 28th of February to 1st of March in the same log file.
-        #
-        # Note: $month_to_dayofyear[12] - $month_to_dayofyear[4] = 245
 
-        $date_wrap_around = $month_to_dayofyear[4];
-        $cvtdate += $month_to_dayofyear[12] * 24 * 60 * 60;
+        my $first_date_cvt_tmp = $first_date_cvt;
+        $wrap_around = 1;
+        $first_date_cvt = &ConvDate ($current_year . ' ' . $first_date, $wrap_around);
 
-	confess if ($cvtdate != &ConvDate ($date_str));
+        # The numbers should have changed (one year less for $first_date_cvt).
+        confess if ($first_date_cvt == $first_date_cvt_tmp);
 	$last_date_cvt = $cvtdate;
 	$last_date = $date_str;
       }
@@ -553,9 +534,9 @@
 {
   my $default = 24 * 60 * 60; # one day
 
-  if ($DEBUG && $first_date_cvt != &ConvDate($first_date))
+  if ($DEBUG && $first_date_cvt != &ConvDate($current_year . ' ' . $first_date, $wrap_around))
   {
-    die '$last_date_cvt != &ConvDate($last_date)';
+    die '$first_date_cvt != &ConvDate($current_year . \' \' . $first_date, $wrap_around)';
   }
   if (!defined($last_date))
   {
@@ -563,9 +544,9 @@
     $last_date_cvt = $first_date_cvt;
     return $default;
   }
-  if ($DEBUG && $last_date_cvt != &ConvDate($last_date))
+  if ($DEBUG && $last_date_cvt != &ConvDate($current_year . ' ' . $last_date, $wrap_around))
   {
-    die '$last_date_cvt != &ConvDate($last_date)';
+    die '$last_date_cvt != &ConvDate($current_year . \' \' . $last_date, $wrap_around)';
   }
   my $result = $last_date_cvt - $first_date_cvt;
   return $result if ($result > 0);
@@ -588,7 +569,7 @@
 
     $month = 1 + index("JanFebMarAprMayJunJulAugSepOctNovDec", $month) / 3;
     my $year = $current_year;
-    $year-- if ($date_wrap_around >= 0);
+    $year-- if ($wrap_around > 0);
 
     $suffix = sprintf ".%02d.%02d.%02d-%02d%s%02d%s%02d",
       $year, $month, $d, $h, $SEPARATOR, $mn, $SEPARATOR, $s;
@@ -757,31 +738,37 @@
   return 1;
 }
 
-# Convert a date to number of seconds since 1st of January.
+# Convert a date to number of seconds since epoch.
 # Leap years are handled correctly, daylight saving is not.
-# Usage: $num = &ConvDate ($date);
-# Date format is "Aug 22 01:49:40"
-sub ConvDate($) {
+# Usage: $num = &ConvDate ($date, $wrap_around);
+# Date format is "2012 Aug 22 01:49:40".
+# The second argument is whether wrapping should be taken into account
+# ($wrap_around is 0 when no change of year has been detected in the logs).
+sub ConvDate($$) {
   my $T = shift;
-  if (!$T)
+  my $wrap = shift;
+  if (!defined($T))
   {
     cluck 'Parameter $T is undefined.' if ($DEBUG);
     return undef;
   }
-  my ($m, $d, $h, $mn, $s) = $T =~ /^(\S\S\S)\s+(\d+)\s+(\d+):(\d+):(\d+)$/;
-  if (!$m)
+  my ($y, $m_name, $d, $h, $mn, $s) = $T =~ /^(\d+)\s+(\S\S\S)\s+(\d+)\s+(\d+):(\d+):(\d+)$/;
+  if (!defined($m_name))
   {
     cluck "Invalid date $T" if ($DEBUG);
     return undef;
   }
-  $m = $month_to_dayofyear{ $m };
-  if (!$m)
+  my $m = index("JanFebMarAprMayJunJulAugSepOctNovDec", $m_name) / 3;
+  if (!defined($m))
   {
     cluck "Invalid month name in $T" if ($DEBUG);
     return undef;
   }
-  $m += $month_to_dayofyear[12] if ($m < $date_wrap_around);
-  return $s + 60 * $mn + 3600 * $h + 86400 * ($d + $m);
+  # Take the previous year if a change of year has been detected and
+  # the date is after May, 1st.
+  $y-- if $wrap > 0 and $m > 4;
+  # Convert the given date to the number of seconds since epoch.
+  return Time::Local::timelocal($s, $mn, $h, $d, $m, $y);
 }
 
 # Compare 2 filenames
@@ -1126,29 +1113,28 @@
 	next unless $year; # bad filename.. strange.
 	my ($start, $end) =
 	  $res[$date_idx - 1] =~ m/^(\w+\s+\d+ \S+) -- (\w+\s+\d+ \S+)$/o;
-        if (!$start)
+        if (!defined($start))
         {
           warn "Invalid line in DB file ignored: $k" if ($DEBUG);
           next;
         }
-	$start = &ConvDate ($start);
-	$end = &ConvDate ($end);
-        if ($start - $end == 0)
+	my $start_sec = &ConvDate ($year . ' ' . $start, 0);
+	my $end_sec = &ConvDate ($year . ' ' . $end, 0);
+        if ($start_sec - $end_sec == 0)
         {
           warn "Time range 0 in DB file ignored: $k" if ($DEBUG);
           next;
         }
 	# 31/12 - 1/1 ?
-	my $inc = $end < $start ? 1 : 0;
-	$start += (($year - 1970) * 365 +
-		   int (($year - 1968) / 4)) * 3600 * 24;
-	$year += $inc;
-	$end += (($year - 1970) * 365 + int (($year - 1968) / 4)) * 3600 * 24;
-	$in{$start} = $type_in ? &kb2i($res[$value_in - 1])
+        if ($end_sec < $start_sec) {
+          $end_sec = &ConvDate ($year+1 . ' ' . $end, 0);
+        }
+
+	$in{$start_sec} = $type_in ? &kb2i($res[$value_in - 1])
 	                       : $res[$value_in - 1];
-	$out{$start} = $type_out ? &kb2i($res[$value_out - 1])
+	$out{$start_sec} = $type_out ? &kb2i($res[$value_out - 1])
 	                         : $res[$value_out - 1];
-	$dates{$start} = $end;
+	$dates{$start_sec} = $end_sec;
       }
       my ($xmax, $ymax) = (500, 170);
       &Chrono ("$IMG_dir/$filename", $title, $color_bg, $xmax, $ymax,
