Removed /usr/local from CDPATH
[clearscm.git] / lib / DateUtils.pm
index ef11a89..f8bfc1c 100644 (file)
@@ -60,7 +60,7 @@ use Time::Local;
 use Display;
 use Utils;
 
-our @EXPORT = qw (
+our @EXPORT = qw(
   Add
   Age
   Compare
@@ -79,6 +79,7 @@ our @EXPORT = qw (
   YMDHMS
   timestamp
   ymdhms
+  MDYHMS2SQLDatetime
 );
 
 my @months = (
@@ -101,11 +102,11 @@ my $SECS_IN_HOUR = $SECS_IN_MIN * 60;
 my $SECS_IN_DAY  = $SECS_IN_HOUR * 24;
 
 # Forwards
-sub Today2SQLDatetime ();
-sub DateToEpoch ($);
-sub EpochToDate ($);
+sub Today2SQLDatetime();
+sub DateToEpoch($);
+sub EpochToDate($);
 
-sub ymdhms {
+sub ymdhms(;$) {
   my ($time) = @_;
 
   $time ||= time;
@@ -138,34 +139,34 @@ sub ymdhms {
   return $year, $mon, $mday, $hour, $min, $sec;
 } # ymdhms
 
-sub julian ($$$) {
+sub julian($$$) {
   my ($year, $month, $day) = @_;
 
   my $days = 0;
   my $m    = 1;
 
-  foreach (@months) {
+  for (@months) {
     last if $m >= $month;
     $m++;
     $days += $_;
-  } # foreach
+  } # for
 
   return $days + $day;
 } # julian
 
-sub _is_leap_year ($) {
+sub _is_leap_year($) {
   my ($year) = @_;
-  
+
   return 0 if $year % 4;
   return 1 if $year % 100;
   return 0 if $year % 400;
-  
+
   return 1; 
 } # _is_leap_year
 
-sub Add ($%) {
+sub Add($%) {
   my ($datetime, %parms) = @_;
-  
+
 =pod
 
 =head2 Add ($datetime, %parms)
@@ -222,47 +223,47 @@ Returns:
     'days',
     'months',
   );
-  
-  foreach (keys %parms) {
+
+  for (keys %parms) {
     unless (InArray ($_, @validKeys)) {
       croak "Invalid key in DateUtils::Add: $_";
     } # unless
-  } # foreach
-  
+  } # for
+
   my $epochTime = DateToEpoch $datetime;
-  
+
   my $amount = 0;
-  
+
   $parms{seconds} ||= 0;
   $parms{minutes} ||= 0;
   $parms{hours}   ||= 0;
   $parms{days}    ||= 0;
-  
+
   $amount += $parms{days}    * $SECS_IN_DAY;
   $amount += $parms{hours}   * $SECS_IN_HOUR;
   $amount += $parms{minutes} * $SECS_IN_MIN;
   $amount += $parms{seconds};
-    
+
   $epochTime += $amount;
 
   $datetime = EpochToDate $epochTime;
-  
+
   if ($parms{month}) {
     my $years  = $parms{month} / 12;
     my $months = $parms{month} % 12;
-     
+
     my $month = substr $datetime, 5, 2;
-    
+
     $years += ($month + $months) / 12;
     substr ($datetime, 5, 2) = ($month + $months) % 12;
-    
+
     substr ($datetime, 0, 4) = substr ($datetime, 0, 4) + $years;
   } # if
-  
+
   return $datetime;
 } # Add
 
-sub Age ($) {
+sub Age($) {
   my ($timestamp) = @_;
 
 =pod
@@ -317,7 +318,6 @@ Returns:
     my $leap_days = 0;
 
     for (my $i = $timestamp_year; $i < $today_year; $i++) {
-       
       $leap_days++ if $i % 4 == 0;
     } # for
 
@@ -326,12 +326,12 @@ Returns:
   } # if
 } # Age
 
-sub Compare ($$) {
+sub Compare($$) {
   my ($date1, $date2) = @_;
-  
+
 =pod
 
-=head2 Compare ($date2, $date2)
+=head2 Compare ($date1, $date2)
 
 Compares two datetimes returning -1 if $date1 < $date2, 0 if equal or 1 if
 $date1 > $date2
@@ -371,9 +371,9 @@ Returns:
   return DateToEpoch ($date1) <=> DateToEpoch ($date2);
 } # Compare
 
-sub DateToEpoch ($) {
+sub DateToEpoch($) {
   my ($date) = @_;
-  
+
 =pod
 
 =head2 DateToEpoch ($datetime)
@@ -414,13 +414,13 @@ Returns:
   my $hour    = substr $date, 11, 2;
   my $minute  = substr $date, 14, 2;
   my $seconds = substr $date, 17, 2;
-  
+
   my $days;
 
   for (my $i = 1970; $i < $year; $i++) {
     $days += _is_leap_year ($i) ? 366 : 365;
   } # for
-  
+
   my @monthDays = (
     0,
     31, 
@@ -435,23 +435,22 @@ Returns:
     304,
     334,
   );
-  
+
   $days += $monthDays[$month - 1];
-  
-  $days++
-    if _is_leap_year ($year) and $month > 2;
-    
- $days += $day - 1;
-  
+
+  $days++ if _is_leap_year ($year) and $month > 2;
+
+  $days += $day - 1;
+
   return ($days   * $SECS_IN_DAY)
        + ($hour   * $SECS_IN_HOUR)
        + ($minute * $SECS_IN_MIN)
        + $seconds;
 } # DateToEpoch
 
-sub EpochToDate ($) {
+sub EpochToDate($) {
   my ($epoch) = @_;
-  
+
 =pod
 
 =head2 EpochToDate ($epoch)
@@ -486,23 +485,23 @@ Returns:
 
 =cut
 
-  my $year = 1970;
   my ($month, $day, $hour, $minute, $seconds);
+
+  my $year         = 1970;
   my $leapYearSecs = 366 * $SECS_IN_DAY;
   my $yearSecs     = $leapYearSecs - $SECS_IN_DAY;
-  
+
   while () {
     my $amount = _is_leap_year ($year) ? $leapYearSecs : $yearSecs;
-    
-    last
-      if $amount > $epoch;
-      
+
+    last if $amount > $epoch;
+
     $epoch -= $amount;
     $year++;
   } # while
-  
+
   my $leapYearAdjustment = _is_leap_year ($year) ? 1 : 0;
-  
+
   if ($epoch >= (334 + $leapYearAdjustment) * $SECS_IN_DAY) {
     $month = '12';
     $epoch -= (334 + $leapYearAdjustment) * $SECS_IN_DAY;
@@ -546,18 +545,18 @@ Returns:
   $epoch   = $epoch % $SECS_IN_HOUR;
   $minute  = int ($epoch / $SECS_IN_MIN);
   $seconds = $epoch % $SECS_IN_MIN;
-  
+
   $day     = "0$day"     if $day     < 10;
   $hour    = "0$hour"    if $hour    < 10;
   $minute  = "0$minute"  if $minute  < 10;
   $seconds = "0$seconds" if $seconds < 10;
-  
+
   return "$year-$month-$day $hour:$minute:$seconds";
 } # EpochToDate
 
-sub UTCTime ($) {
+sub UTCTime($) {
   my ($datetime) = @_;
-  
+
 =pod
 
 =head2 UTCTime ($epoch)
@@ -596,22 +595,22 @@ Returns:
   my ($sec, $min, $hour, $mday, $mon, $year) = gmtime (
     DateToEpoch ($datetime) - (timegm (@localtime) - timelocal (@localtime))
   );
-      
+
   $year += 1900;
   $mon++;
 
-  $sec  = '0' . $sec  if $sec  < 10;  
-  $min  = '0' . $min  if $min  < 10;  
-  $hour = '0' . $hour if $hour < 10;  
+  $sec  = '0' . $sec  if $sec  < 10;
+  $min  = '0' . $min  if $min  < 10;
+  $hour = '0' . $hour if $hour < 10;
   $mon  = '0' . $mon  if $mon  < 10;
   $mday = '0' . $mday if $mday < 10;
-      
+
   return "$year-$mon-${mday}T$hour:$min:${sec}Z";  
 } # UTCTime
 
-sub UTC2Localtime ($) {
+sub UTC2Localtime($) {
   my ($utcdatetime) = @_;
-  
+
   # If the field does not look like a UTC time then just return it.
   return $utcdatetime unless $utcdatetime =~ /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/;
 
@@ -620,17 +619,17 @@ sub UTC2Localtime ($) {
 
   my @localtime = localtime;
 
-  return EpochToDate (
+  return EpochToDate(
     DateToEpoch ($utcdatetime) + (timegm (@localtime) - timelocal (@localtime))
   );
 } # UTC2Localtime
 
-sub FormatDate ($) {
-  my ($date) = @_;
+sub FormatDate($;$) {
+  my ($date, $separator) = @_;
 
 =pod
 
-=head2 FormatDate ($date)
+=head2 FormatDate ($date, $separator)
 
 Formats date
 
@@ -644,6 +643,10 @@ Parameters:
 
 Date in YYYYMMDD
 
+=tiem $separator
+
+If specified, indicates that $date has separators (e.g. 2021-07-04).
+
 =back
 
 =for html </blockquote>
@@ -662,14 +665,20 @@ Returns:
 
 =cut
 
-  return substr ($date, 4, 2)
-       . "/"
-       . substr ($date, 6, 2)
-       .  "/"
-       . substr ($date, 0, 4);
+  unless ($separator) {
+    return substr($date, 4, 2) . '/'
+         . substr($date, 6, 2) . '/'
+         . substr($date, 0, 4);
+  } else {
+    return substr($date, 5, 2)
+         . '/'
+         . substr($date, 8, 2)
+         . '/' 
+         . substr($date, 0, 4);
+  } # if
 } # FormatDate
 
-sub FormatTime ($) {
+sub FormatTime($) {
   my ($time) = @_;
 
 =pod
@@ -712,10 +721,12 @@ Returns:
 
   $hours = $hours - 12 if $hours > 12;
 
+  $hours = "0$hours" if length $hours == 1;
+
   return "$hours:$minutes $AmPm";
 } # FormatTime
 
-sub MDY (;$) {
+sub MDY(;$) {
   my ($time) = @_;
 
 =pod
@@ -757,7 +768,7 @@ Returns:
   return "$mon/$mday/$year";
 } # MDY
 
-sub SQLDatetime2UnixDatetime ($) {
+sub SQLDatetime2UnixDatetime($) {
   my ($sqldatetime) = @_;
 
 =pod
@@ -817,7 +828,7 @@ Returns:
   return $months{$month} . " $day, $year \@ $time";
 } # SQLDatetime2UnixDatetime
 
-sub SubtractDays ($$) {
+sub SubtractDays($$) {
   my ($timestamp, $nbr_of_days) = @_;
 
 =pod
@@ -866,6 +877,14 @@ Returns:
   my $month = substr $timestamp, 5, 2;
   my $day   = substr $timestamp, 8, 2;
 
+  # We are not properly accounting for leap days but this is just a rough
+  # estimate anyway
+  if ($nbr_of_days > 365) {
+    $year -= int $nbr_of_days / 365;
+
+    $nbr_of_days = $nbr_of_days % 365;
+  } # if
+
   # Convert to Julian
   my $days = julian $year, $month, $day;
 
@@ -911,7 +930,7 @@ Returns:
   return $year . "-" . $month . "-" . $days . substr $timestamp, 10;
 } # SubtractDays
 
-sub Today2SQLDatetime () {
+sub Today2SQLDatetime() {
 
 =pod
 
@@ -945,10 +964,10 @@ Returns:
 
 =cut
 
-  return UnixDatetime2SQLDatetime (scalar (localtime));
+  return UnixDatetime2SQLDatetime(scalar localtime);
 } # Today2SQLDatetime
 
-sub UnixDatetime2SQLDatetime ($) {
+sub UnixDatetime2SQLDatetime($) {
   my ($datetime) = @_;
 
 =pod
@@ -1057,7 +1076,7 @@ Returns:
   unless ($months{$month_name}) {
     $month_name = substr $datetime, 8, 3;
   } # unless
-  
+
   my $month = $months{$month_name};
   my $time  = substr $datetime, 11, 8;
 
@@ -1069,12 +1088,12 @@ Returns:
     warning "Year undefined for $orig_datetime\nReturning today's date";
     return Today2SQLDatetime;
   } # unless
-    
+
   unless ($month) {
     warning "Month undefined for $orig_datetime\nReturning today's date";
     return Today2SQLDatetime;
   } # unless
-  
+
   unless ($day) {
     warning "Day undefined for $orig_datetime\nReturning today's date";
     return Today2SQLDatetime;
@@ -1088,7 +1107,7 @@ Returns:
   return "$year-$month-$day $time";
 } # UnixDatetime2SQLDatetime
 
-sub YMD (;$) {
+sub YMD(;$) {
   my ($time) = @_;
 
 =pod
@@ -1130,7 +1149,7 @@ Returns:
   return "$year$mon$mday";
 } # YMD
 
-sub YMDHM (;$) {
+sub YMDHM(;$) {
   my ($time) = @_;
 
 =pod
@@ -1172,7 +1191,7 @@ Returns:
   return "$year$mon$mday\@$hour:$min";
 } # YMDHM
 
-sub YMDHMS (;$) {
+sub YMDHMS(;$) {
   my ($time) = @_;
 
 =pod
@@ -1214,7 +1233,7 @@ Returns:
   return "$year$mon$mday\@$hour:$min:$sec";
 } # YMDHMS
 
-sub timestamp (;$) {
+sub timestamp(;$) {
   my ($time) = @_;
 
 =pod