How this calculator works
Age is counted the same way a person counts it by hand: complete years since the birth date, then complete months since the most recent birthday, then the remaining days since the most recent full month. This calendar-correct method is deliberately different from dividing total days lived by 365 (or 365.25) — that shortcut drifts because months have different lengths and leap years add an extra day, so it can be off by a day or more depending on exactly which months and leap years fall inside the span.
Total days, weeks, and hours lived are computed separately, directly from the calendar-day gap between the two dates — an exact count, not an estimate.
Worked example
Someone born on June 15, 1990, with age calculated as of August 5, 2026:
- From June 15, 1990 to June 15, 2026 is exactly 36 complete years.
- From June 15, 2026 to July 15, 2026 is 1 complete month.
- From July 15, 2026 to August 5, 2026 is 21 days (July has 31 days: 16 remaining days in July, plus 5 days into August).
Exact age: 36 years, 1 month, 21 days — 13,200 total days lived, born on a Friday, with a next birthday on June 15, 2027 (turning 37).
Formulas in Excel, SQL & code
The same calendar-correct method this calculator uses, in the tools people most often ask about. Each returns complete years (and, where shown, complete months and remaining days) as of today — swap in a specific date where noted.
Excel / Google Sheets
=DATEDIF(B1,TODAY(),"y")&" years, "&DATEDIF(B1,TODAY(),"ym")&" months, "&DATEDIF(B1,TODAY(),"md")&" days"
B1 holds the birth date. DATEDIF’s “y” gives complete years, “ym” gives remaining months, and “md” gives remaining days — the same three-part breakdown this page shows. Works identically in Google Sheets.
SQL Server
SELECT DATEDIFF(YEAR, birth_date, GETDATE())
- CASE WHEN (MONTH(birth_date) > MONTH(GETDATE()))
OR (MONTH(birth_date) = MONTH(GETDATE()) AND DAY(birth_date) > DAY(GETDATE()))
THEN 1 ELSE 0 END AS age;
DATEDIFF(YEAR, ...) alone counts calendar-year boundaries crossed, not complete years — the CASE expression subtracts one when this year’s birthday hasn’t happened yet.
MySQL / MariaDB
SELECT TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) AS age;
TIMESTAMPDIFF with a YEAR unit already accounts for whether the birthday has occurred this year, so no extra adjustment is needed.
PHP
$birth = new DateTime('1990-06-15');
$today = new DateTime('today');
$age = $birth->diff($today);
echo $age->y . " years, " . $age->m . " months, " . $age->d . " days";
Java
LocalDate birthDate = LocalDate.of(1990, 6, 15);
LocalDate today = LocalDate.now();
Period age = Period.between(birthDate, today);
System.out.println(age.getYears() + " years, " + age.getMonths()
+ " months, " + age.getDays() + " days");
Oracle
SELECT FLOOR(MONTHS_BETWEEN(SYSDATE, birth_date) / 12) AS age
FROM dual;
MONTHS_BETWEEN returns a fractional month count between the two dates; dividing by 12 and flooring gives complete years.
MS Access
Age: DateDiff("yyyy",[BirthDate],Date()) - IIf(Format([BirthDate],"mmdd")>Format(Date(),"mmdd"),1,0)
Same logic as the SQL Server example: DateDiff(“yyyy”, ...) counts year boundaries, and the IIf/Format comparison subtracts one if this year’s birthday hasn’t occurred yet.
SAS
age = intck('year', birth_date, today(), 'continuous');
The “continuous” alignment argument makes INTCK count whole elapsed years rather than calendar-year boundaries crossed — without it, INTCK would overcount the same way a plain year subtraction does.
Sources and methodology
Age calculation: the complete-years/complete-months/remaining-days method is the standard calendar-correct approach used by date libraries generally (including the language/database examples above), not a bespoke algorithm.
Calendar: the proleptic Gregorian calendar, used consistently for all dates regardless of era.