Age Calculator

Level: Intermediate 30–60 min

Concepts: Edge CasesAlgorithms

Solutions: C# | TypeScript | Python


Calculate a person’s age at a given date. Do this by creating a single public method that takes a person’s birth date and a target date to compare to and returns their age as an integer.

Examples

Zenith was born on 28 October 2016 how old was she on 5 November 2022? Answer 6.

Edge Cases to Consider

  • Leap years and handling of Feb 29 birthdays
  • Birthdate is after the target date (future date)
  • Birthdate or target date is today
  • Time zones affecting the calculation

Bonus

In the age of Social Media birthday, weeks are a big deal. To allow for this, add a new method to the Calculator that returns the start date of the person’s birthday week, as a string, according to the following rules.

  • If my birthday is Thursday-Saturday, my birthday week starts on the Sunday of that week. E.g. If I was born on September 9, 2017, my birthday week will start on September 3, 2017.
  • If my birthday is Sunday-Wednesday, my birthday week starts 6 days back. E.g. If I was born on September 3, 2017, my birthday week will start on August 28, 2017.

Reference Walkthrough

Reference implementations in C#, TypeScript, and Python live at tddbuddy-reference-katas/age-calculator. The reference exposes the canonical primitive — calculate(birthdate, today) — with the reference date passed in explicitly rather than read from the system clock. That discipline is the teaching point: ambient-clock access turns every birthday-boundary scenario (“on her seventh birthday she is 7”) into a flake unless tests can fix “today” to a specific date. Eleven scenarios cover the TDD Buddy example, birthday-as-boundary (exact-day turn-over), day-before-birthday, same-day-as-today, the leap-day-baby triad (Feb 28 in non-leap → still the previous age, Mar 1 in non-leap → aged up, Feb 29 in leap → aged up exactly), the across-the-year-boundary newborn, and a future-birthdate guard.

  • C# (.NET 8, xUnit, FluentAssertions 6.12.0) — walkthroughpublic static int Calculate(DateOnly birthdate, DateOnly today)
  • TypeScript (Node 20, Vitest 1.6, TS 5 strict) — walkthrough — UTC-disciplined Date: construct via Date.UTC(...), read via getUTCFullYear() / getUTCMonth() / getUTCDate() so calendar components stay stable across host time zones
  • Python (3.11, pytest) — walkthroughdatetime.date with native tuple comparison: (today.month, today.day) < (birthdate.month, birthdate.day) is the cleanest of the three languages for this rule

The leap-day-in-a-non-leap-year rule (a Feb 29 baby turns older on March 1, not Feb 28) falls out of the (month, day) comparison without any special case — (2, 28) < (2, 29) is still true, so the age decrement fires correctly. The future-birthdate guard throws an idiomatic exception (ArgumentException / Error / ValueError) with the byte-identical message birthdate is after today.

This kata ships in Agent Full-Bake mode at high gear (F1 tier): the algorithm is small enough to land as one commit per language, with a brief walkthrough noting there are no builders because the date type comes from the standard library and the inputs/outputs are the domain. See the repo’s Gears section for when high gear is the right call.

Solutions

You can find all language solutions here Age Calculator Solutions

Or you can select a specific language below.


  • Examples Pin Intent. Properties Pin the Invariants.
    Example-based tests anchor scenarios in the team's vocabulary. Property-based tests anchor invariants across the input space. The agent needs both axes, and most suites only carry one.
  • Katas Are Rehearsal, Not Performance
    You don't practice TDD on production code. You practice on katas and bring the muscle memory to production. The gap between knowing TDD and doing TDD is reps.
  • The Test Pyramid Was an Economic Argument
    The test pyramid was not a quality law. It was a cost structure: unit tests were cheap, integration tests were expensive, so you wrote many of the first and few of the second. Agents collapsed the cost of writing tests at every level, and the cheapest test that still tells the truth is the one that pins a seam the agent cannot fake.