开发者

How to express the difference between two dates in a human-readable format

If I have two dates - $end_date and $start_date, how can I express the difference between the two in a format such as "2 Years : 4 Months : 2 Days"?

I know that 开发者_JS百科I can get the difference between the two dates like so:

$dif=strtotime($end_date)-strtotime($today);

But how can I convert that result into the human-readable format, like that shown above?


This is how you can format a timestamp:

echo date('d-m-Y', strtotime($end_date)) // for DD-MM-YYYY format

Are you looking to calculate the difference between 2 dates, in number days?

EDIT: code to find the difference between dates in "XXyear YYmonth ZZday". The code assumes that start and end dates are in YYYY-MM-DD format. If that's not the case for you, please either change them to YYYY-MM-DD format, OR change the arguments to mktime() accordingly.

$endDate = '2011-03-01';
$startDate = '2011-02-02';
$daysPerYear = 365;
$daysPerMonth = 30.4;
$diffDay = $diffMonth = $diffYear = 0;

$endDateTs = mktime(0, 0, 0, substr($endDate, 5, 2), substr($endDate, 8, 2), substr($endDate, 0, 4));
$startDateTs = mktime(0, 0, 0, substr($startDate, 5, 2), substr($startDate, 8, 2), substr($startDate, 0, 4));
$diffDay = ($endDateTs - $startDateTs) / 60 / 60/ 24;   // difference between 2 dates in number of days
$diffYear = floor($diffDay / $daysPerYear); // difference in years
$diffDay = $diffDay % $daysPerYear; // balance days
$diffMonth = floor($diffDay / $daysPerMonth);   // difference in months
$diffDay = ceil($diffDay % $daysPerMonth); // balance days
echo ($diffYear ? $diffYear . 'year ' : '') . ($diffMonth ? $diffMonth . 'month ' : '') . ($diffDay ? $diffDay . 'day' : '');

Note: I haven't tested the code for all possible date combinations, including leap year etc. Please feel free to tweak as needed.

Hope this helps.


If a coarse difference is enough ("2 years ago"), then you might want to try the Date_HumanDiff PEAR package.


The clean, DRY, professional, modern way to do this is to create two datetime objects and call diff(). The generated diff object will automatically populate year, month, day values for you.

Then you only need to iterate through a lookup array containing your desired units and implode any non-zero results into the plain English output string.

Code (Demo)

$startDate = '2001-04-20';
$endDate = '2015-11-29';
$diff = (new DateTime($startDate))->diff(new DateTime($endDate));

$lookup = [
    'y' => 'Year',
    'm' => 'Month',
    'd' => 'Day',
];

$elements = [];
foreach ($lookup as $property => $word) {
    if ($diff->$property) {
        $elements[] = "{$diff->$property} $word" . ($diff->$property !== 1 ? 's' : '');
    }
}
echo implode(' : ', $elements);
// 14 Years : 7 Months : 9 Days


function is_leap_year($year)
{
    if($year % 4 == 0)
    {
        if($year % 100 == 0)
        {
            if($year % 400 == 0)
            {
                return true;
            }
            else 
            {
                return false;
            }
        }
        else
        {
            return true;
        }
    }
    else 
    {
        return false;
    }
}

function calculate_date($now, $end){
    $years = date('Y', strtotime($end)) - date('Y', strtotime($now)) ;
    if($years < 0)
    {
        return "Error: year";
    }
    $mounths = date('m', strtotime($end)) - date('m', strtotime($now)) ;
    if($mounths < 0)
    {
        if($years < 1)
        {
            return "Error: mounth and year";
        }
        else 
        {
            $years --;
            $mounths += 12;
        }
    }
    $days = date('d', strtotime($end)) - date('d', strtotime($now)) ;
    if($days < 0){
        if($mounths < 1)
        {
            if($years < 1)
            {
                return "Error: day, mounth and year";
            }
            else 
            {
                $years --;
                $mounths += 12;
            }
        }
        else 
        {
            $mounths --;
            switch (date('m', strtotime($now)))
            {
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    $days +=31;
                    break;
                case 4:
                case 6:
                case 9:
                case 11:
                    $days +=30;
                    break;
                case 2:
                    if(is_leap_year(date('Y', strtotime($now))))
                    {
                        $days += 29;
                        break;
                    }
                    else
                    {
                        $days += 28;
                        break;
                    }
            }
        }
    }
    return  $years . " Years : " . $mounths . " Months : " . $days . " Days Remaining.";
}

$end_date = new DateTime('2011-08-05');
$end_date = $end_date->format('d-m-Y');
$today = date('d-m-Y');

$remaining = calculate_date($today, $end_date);

echo $remaining;

And if you want to format end_date you can use: date('d-m-Y', strtotime($end_date)) And after that you can calculate remaining time with calculate_date .

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜