C++ Age Calculator Project
Enter a birth date and get an exact age in years, months, and days.
What you will build
'How old am I, exactly?' sounds simple until you borrow days from the previous month and months from the year. This project is a focused drill in date arithmetic and validating impossible dates like 31 February.
What you will learn
- Representing a date as a struct
- Date subtraction with borrowing
- Validating day/month/year ranges
- Leap-year-aware month lengths
Feature checklist
- Takes a full date of birth (day, month, year)
- Uses today's date automatically
- Exact age in years, months, and days
- Rejects invalid dates and future birth dates
- Bonus: total days lived
Starter code
#include <iostream>
#include <chrono>
#include <ctime>
struct Date { int d, m, y; };
int dim(int m, int y) { // days in month
static const int t[] = {31,28,31,30,31,30,31,31,30,31,30,31};
bool leap = (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
return (m == 2 && leap) ? 29 : t[m - 1];
}
Date age(Date birth, Date today) {
Date a = today;
if (a.d < birth.d) { // borrow days
a.d += dim(a.m == 1 ? 12 : a.m - 1, a.m == 1 ? a.y - 1 : a.y);
--a.m;
}
if (a.m < birth.m) { a.m += 12; --a.y; } // borrow months
return { a.d - birth.d, a.m - birth.m, a.y - birth.y };
}
int main() {
auto now = std::chrono::system_clock::now();
std::time_t tt = std::chrono::system_clock::to_time_t(now);
std::tm lt = *std::localtime(&tt);
Date today{ lt.tm_mday, lt.tm_mon + 1, lt.tm_year + 1900 };
Date a = age({15, 6, 2000}, today);
std::cout << "Age: " << a.y << "y " << a.m << "m " << a.d << "d\n";
}Full walkthrough
Step 1: Represent dates with a tiny struct
struct Date { int d, m, y; } — three ints, no behaviour. Two Dates drive everything: the birth date the user types, and today's date, which the program gets itself. Keeping them the same type is what lets one subtraction function handle both.
Step 2: Get today's date from the system clock
std::chrono::system_clock::now() gives the current instant; convert with to_time_t and localtime (from <ctime>) into a std::tm, then build Date{tm_mday, tm_mon + 1, tm_year + 1900}. The +1 and +1900 corrections are the same ones the Digital Clock project warned about — tm counts months from 0 and years from 1900.
Step 3: Write dim() — days in month, leap-aware
dim(m, y) mirrors the calendar project's table, returning 29 for February when (y % 4 == 0 && y % 100 != 0) || y % 400 == 0. age() needs it because 'borrow days from last month' is meaningless until you know how many days last month had — for the birth year, not today's.
Step 4: Subtract with borrowing, like primary-school maths
age() copies today into a result, then borrows in two passes: if the result day is smaller than the birth day, add last month's length to the day and decrement the month; if the result month is then smaller than the birth month, add 12 and decrement the year. Finally subtract field by field. The ORDER matters — borrow days first, because borrowing days can push the month down.
if (a.d < birth.d) {
a.d += dim(a.m - 1 < 1 ? 12 : a.m - 1,
a.m - 1 < 1 ? a.y - 1 : a.y);
--a.m;
}Step 5: Validate before you calculate
Reject a birth date in the future, a month outside 1–12, and a day beyond dim(m, y) for that month and year — 31 February must be refused, not 'calculated'. Validation is boring and it is also the difference between an age calculator and a random number generator.
Step 6: Add total days lived as the bonus
Count days by summing whole years (365 each, plus one per leap year crossed), whole months via dim(), and the remaining days. It reuses dim() three ways — a good check that your helper is as general as it should be.
Step 7: Test against ages you know
Someone born 15 June 2000, checked on 23 October 2026, is exactly 26 years, 4 months, 8 days. Also test the awkward cases: born on the 31st (borrowing into a 30-day month), born 29 February (leap-day birthdays), and born exactly today (0 years, 0 months, 0 days — not an error).
Common mistakes
- Borrowing days using the CURRENT month's length instead of the previous month's — the classic off-by-a-few-days bug.
- Forgetting tm_mon + 1 and tm_year + 1900 when building today's Date, shifting every age by a month and 1900 years.
- Validating the day against 31 for every month, waving 31 April and 30 February straight through.
Compile and run
g++ -std=c++17 -o age age.cppSample run
$ ./age
Enter your date of birth (day month year):
> 15 6 2000
Today is 23 October 2026.
Your age: 26 years, 4 months, 8 days
Total days lived: 9626
$ ./age
Enter your date of birth (day month year):
> 29 2 2024
Today is 23 October 2026.
Your age: 2 years, 7 months, 24 days
Total days lived: 967
$ ./age
Enter your date of birth (day month year):
> 31 2 2000
That date does not exist — February 2000 had 29 days.Try it in your browser
No browser demo is included for this project. Build the C++ version below — that is the real program.