Robson » Little Red Book » Days between dates

Chapter 2 - Question 7

Given two dates between January 1st, 1901 and December 31st, 1999, calculate the number of days between the dates.

Solution 1

Unfortunately, Windows doesn't support negative numbers for the PHP date functions, so I can't do this the easy way.

<?
   // the number of days per month;
   $days_per_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
 
   // generate a random first day and last day between 1/1/1901 and 31/25/1999
   $day_start = array(0, mt_rand(1, 12), mt_rand(1901,1950));
   $day_end = array(0, mt_rand(1, 12), mt_rand(1951,1999));
 
   // generate a random number of days for each month
   $day_start[0] = mt_rand(1, $days_per_month[$day_start[1]-1]);
   $day_end[0] = mt_rand(1, $days_per_month[$day_end[1]-1]);
   
   // first, work out the number of days elapsed in the first year past the start date
   // days elapsed in that month
   // so if the month has 30 days and this is day 7, this will be 23
   $days = $days_per_month[$day_start[1]-1] - $day_start[0];
   // then add the days for each month after
   for ($n = $day_start[1]; $n < 12; $n++)
       // add the number of days that month
       $days += $days_per_month[$n];
       
   // if that year was a leap year
   // check if it's january or (february and before the leap day)
   if (!($day_start[2] % 4) && ($day_start[1] == 1 || ($day_start[1] == 2 && $day_start[0] < 29)))
       // add the leap day
       $days++;
       
   // second, work out the number of days elapsed in the last year
   // take away one for the current day (the question states 'inbetween')
   $days += $day_end[0]-1;
   
   // loop through each remaining month
   for ($n = 0; $n < $day_end[1]-1; $n++)
       // and add in the days for that month
       $days += $days_per_month[$n];
       
   // if that year was a leap year
   // and if the month was after february
   if (!($days_end[2] % 4) && $day_end[2] > 2)
       // add the leap day
       $days++;
   
   // now loop through all the years inbetween
   for ($n = $day_start[2]+1; $n < $day_end[2]; $n++)
   {
       $days += 365;
       // check if it was a leap year
       if (!($n % 4))
           // add the leap day
           $days++;
   }
   
   // output the number of days and the start/end date    
   echo 'There are ' . number_format($days) . ' days between ' . implode('/', $day_start) . ' and ' . implode('/', $day_end);
?>

Which produces:

There are 8,415 days between 28/4/1947 and 12/5/1970

Solution 2

This can be done a lot easier if using dates between 1971 and 1937.

<?
   // convert random dates to unix timestamp
   // hour minute second month day year
   $start = mktime(1, 1, 1, mt_rand(1, 28), mt_rand(1, 12), mt_rand(1972, 2000));
   $end = mktime(1, 1, 1, mt_rand(1, 28), mt_rand(1, 12), mt_rand(2001, 2036));
   
   // work out the number of seconds between and then divide by seconds per day
   $inbetween = ($end-$start) / (60 * 60 * 24);
   
   // output the number of days and the start/end date    
   echo 'There are ' . number_format($inbetween) . ' days between ' . date('F jS, Y', $start) . ' and ' . date('F jS, Y', $end);
?>

Which produces:

There are 2,379 days between June 7th, 1998 and December 11th, 2004

Log

© 2004-17 robson | cc unless stated