×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

Coding

Calculating the difference between dates in years, months, and days by sleipnir214
Posted: 24 Apr 03

<?php
/*
    License:  do whatever you want with this code
    
    Disclaimer:  This code works well on my system, but may not on yours.  Use
    with circumspection and trepidation.  If this code blows up your system,
    I recommend vituperation.
*/



/*
    function smoothdate simply takes a year, month, and a day, and
    concatenates them in the form YYYYMMDD
    
    the function date_difference uses this function
*/

function smoothdate ($year, $month, $day)
{
    return sprintf ('%04d', $year) . sprintf ('%02d', $month) . sprintf ('%02d', $day);
}


/*
    function date_difference calculates the difference between two dates in
    years, months, and days.  There is a ColdFusion funtion called, I
    believe, date_diff() which performs a similar function.
    
    It does not make use of 32-bit unix timestamps, so it will work for dates
    outside the range 1970-01-01 through 2038-01-19.  This function works by
    taking the earlier date finding the maximum number of times it can
    increment the years, months, and days (in that order) before reaching
    the second date.  The function does take yeap years into account, but does
    not take into account the 10 days removed from the calendar (specifically
    October 5 through October 14, 1582) by Pope Gregory to fix calendar drift.
    
    As input, it requires two associative arrays of the form:
    array (    'year' => year_value,
            'month' => month_value.
            'day' => day_value)
    
    The first input array is the earlier date, the second the later date.  It
    will check to see that the two dates are well-formed, and that the first
    date is earlier than the second.
    
    If the function can successfully calculate the difference, it will return
    an array of the form:
    array (    'years' => number_of_years_different,
            'months' => number_of_months_different,
            'days' => number_of_days_different)
            
    If the function cannot calculate the difference, it will return FALSE.
    
*/

function date_difference ($first, $second)
{
    $month_lengths = array (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

    $retval = FALSE;

    if (    checkdate($first['month'], $first['day'], $first['year']) &&
            checkdate($second['month'], $second['day'], $second['year'])
        )
    {
        $start = smoothdate ($first['year'], $first['month'], $first['day']);
        $target = smoothdate ($second['year'], $second['month'], $second['day']);
                            
        if ($start <= $target)
        {
            $add_year = 0;
            while (smoothdate ($first['year']+ 1, $first['month'], $first['day']) <= $target)
            {
                $add_year++;
                $first['year']++;
            }
                                                                                                            
            $add_month = 0;
            while (smoothdate ($first['year'], $first['month'] + 1, $first['day']) <= $target)
            {
                $add_month++;
                $first['month']++;
                
                if ($first['month'] > 12)
                {
                    $first['year']++;
                    $first['month'] = 1;
                }
            }
                                                                                                                                                                            
            $add_day = 0;
            while (smoothdate ($first['year'], $first['month'], $first['day'] + 1) <= $target)
            {
                if (($first['year'] % 100 == 0) && ($first['year'] % 400 == 0))
                {
                    $month_lengths[1] = 29;
                }
                else
                {
                    if ($first['year'] % 4 == 0)
                    {
                        $month_lengths[1] = 29;
                    }
                }
                
                $add_day++;
                $first['day']++;
                if ($first['day'] > $month_lengths[$first['month'] - 1])
                {
                    $first['month']++;
                    $first['day'] = 1;
                    
                    if ($first['month'] > 12)
                    {
                        $first['month'] = 1;
                    }
                }
                
            }
                                                                                                                                                                                                                                                        
            $retval = array ('years' => $add_year, 'months' => $add_month, 'days' => $add_day);
        }
    }
                                                                                                                                                                                                                                                                                
    return $retval;
}


/*
    This code is merely an example of use of the function
*/

print '<pre>';
$begin = array ('year' => 2001, 'month' => 3, 'day' => 14);
$end = array ('year' => 2004, 'month' => 3, 'day' => 14);

$foo = date_difference ($begin, $end);
if ($foo !== FALSE)
{
    print_r ($foo);
}
else
{
    print 'FALSE';
}

?>

Back to PHP FAQ Index
Back to PHP Forum

My Archive

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close