Jump to content

Accurate years between two dates with day/hour rollover precision...


edoggie

Recommended Posts

I need to get the number of years past between two dates, with accuracy down to the 12AM hour on the rollover day.  So basically on the exact hour a new year begins I am returning 1 year, 2 years, etc.

 

This is the code I have thus far

  function datediff_new($interval, $datefrom, $dateto, $using_timestamps = false)
   {
      if (!$using_timestamps) {
         $datefrom = strtotime($datefrom, 0);
         $dateto = strtotime($dateto, 0);
      }
      
      if ($interval == 'yyyy') {
         
         $returned_days = $this->count_days($datefrom,$dateto);
         //echo "Number of returned days {$returned_days}<br />";
         
         //echo "Number of returned years {$return_years}";
         
         $leap_days = $this->leap_years(date('Y',$datefrom), date('Y',$dateto));
         
         if (date('Y',$dateto) < 12)
         {
            $leap_days-1;
            echo "Reduce by 1 year";
         }
         
         
         $return_years = floor($returned_days/(365+$leap_days));
         echo 'Number of days: ';
         echo  365+$leap_days;
         echo '<br />Return Years: ' . $return_years . '<br />';
         return $return_years;
         
      }
      else {
         die('undefined error vesting_lib - line 1614');
      }
   }
   


   // Will return the number of days between the two dates passed in
   //send in dates as unix timestamp
   function count_days( $a, $b )
   {
      // First we need to break these dates into their constituent parts:
      
      $gd_a = getdate( $a );
      $gd_b = getdate( $b );
      
      // Now recreate these timestamps, based upon noon on each day
      // The specific time doesn't matter but it must be the same each day
      
      $a_new = mktime( 0, 01, 00, $gd_a['mon'], $gd_a['mday'], $gd_a['year'] );
      $b_new = mktime( 0, 01, 00, $gd_b['mon'], $gd_b['mday'], $gd_b['year'] );
      
      // Subtract these two numbers and divide by the number of seconds in a
      // day. Round the result since crossing over a daylight savings time
      // barrier will cause this time to be off by an hour or two.
      return round( floor($b_new - $a_new)  / 86400 );
   }

   function leap_years($start, $end)
   {   
      $extra_days = 0;
      while($start <= $end)
      {
         
         $leap =  (date('L', strtotime("{$start}-01-01"))) ? true : false;
         //echo $leap, '<br /> ';
         
         if ($leap)
         {
            $extra_days++;
         }
         
         $start++;
      }
      return $extra_days;
   }

And this is an example usage of the above code:

$return_years = $this->datediff_new('yyyy', $from_date, $to_date, false);

 

Originally I was using an approximation, the count days function was returning the number of days between two dates, then I was dividing that by "365.24" to get the number of years. Unfortunately this doesn't really work do down to the hour because depending on how many leap years are given in a specific period this number may be more or less.

 

So I added a Leap year function to try to return the number of leap years in the given period. But this doesn't seem to have improved the accuracy.

The definition of the age of something (in years) is the different between the end year and the start year, subtract one if the mm-dd of the end year is less than the mm-dd of the start year. Set $start and $end in the following to any arbitrary dates ($end later than $start) to find the age in years between those two dates -

 

$start = '1985-04-14'; // standard yyyy-mm-dd format
$end = date("Y-m-d");
$age = substr($end, 0, 4) - substr($start, 0, 4) - (substr($end, 5,5) < substr($start, 5,5));
echo "DOB: $start, Age: $age<br />";

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.