Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

polarcubs's avatar

Carbon display age in years, months, day

Hi,

I know this is more of a Carbon question rather than a Laravel question.

Well. I was trying to display a user age in years, months and days (12 years, 7 months and 22 days old). However Carbon age method only return the years. I want something more precise.

What would be a good way to do it?

0 likes
10 replies
danharper's avatar

Carbon extends the base DateTime class, so you can use the diff method, which returns a DateInterval. Then you can use the format method on that:

Carbon::createFromDate(1991, 7, 19)->diff(Carbon::now())->format('%y years, %m months and %d days')
// => "23 years, 6 months and 26 days"

DateInterval::format docs.

13 likes
danharper's avatar

Btw, that can produce a string like "23 years, 0 months and 0 days".

You'll probably want to create $years, $months and $days separately, then form a string from them separately - that'll allow you to skip 0 values.

1 like
JarekTkaczyk's avatar

@polarcubs

/**
 * Display age in format:
 * '%y years, %m months and %d days old'
 * '%y years and %m months old'
 * '%m years and %d days old'
 * 
 * @param  \DateTime $born
 * @param  \DateTime $reference
 * @return string
 *
 * @throws \InvalidArgumentException
 */
function age(DateTime $born, DateTime $reference = null)
{
    $reference = $reference ?: new DateTime;

    if ($born > $reference) 
        throw new \InvalidArgumentException('Provided birthday cannot be in future compared to the reference date.');

    $diff = $reference->diff($born);

    // Not very readable, but all it does is joining age
    // parts using either ',' or 'and' appropriately
    $age = ($d = $diff->d) ? ' and '.$d.' '.str_plural('day', $d) : '';
    $age = ($m = $diff->m) ? ($age ? ', ' : ' and ').$m.' '.str_plural('month', $m).$age : $age;
    $age = ($y = $diff->y) ? $y.' '.str_plural('year', $y).$age  : $age;

    // trim redundant ',' or 'and' parts
    return ($s = trim(trim($age, ', '), ' and ')) ? $s.' old' : 'newborn';
}


// examples:

[1] > age(new DateTime('2000-01-01'));
// '15 years, 1 month and 13 days old'
[2] > age(new DateTime('2 years, 10 days ago'));
// '2 years and 10 days old'
[3] > age(new Carbon('yesterday'));
// '1 day old'
[4] > age(new DateTime);
// 'newborn'
[5] > echo 'On November 5th, 2010 I was ' . age(new DateTime('2000-01-01'), new DateTime('2010-11-05')) . PHP_EOL;
On November 5th, 2010 I was 10 years, 10 months and 4 days old
[6] > age(Carbon::parse('tomorrow'));
PHP Fatal error:  Uncaught exception 'InvalidArgumentException' with message 'Provided birthday cannot be in future compared to the reference date.'
2 likes
kornel's avatar

I also need a method which returns user age. Can anyone advise me where should I put the age() method? In model or in controller? And why. And should it be static? (and why ;) )

Erik's avatar

@kornel You should put it in either presenter or in the model.

In your model for example

public function getAgeAttribute() {
    return // logic...
}

// Or
public function getAge() {
    return // logic...
}
1 like
skac007's avatar
<?php
require 'vendor/autoload.php';
$Born = Carbon\Carbon::create(1986, 1,3);
$Age = $Born->diff(Carbon\Carbon::now())->format('%y Year, %m Months and %d Days');
echo $Age;
1 like
petertmangoro's avatar

a bit late but this can help someone ..

Carbon::parse($date)->diffForHumans([ 'parts'=>3, 'short'=>true, ]),

1 like

Please or to participate in this conversation.