# How to calculate age on a particular date in Years, months, days format?

Lets say my D.O.B is 10/02/1989 and i want to calculate my age on 1st May, 2017, then 28 years, 2 months, and 21 days will be my age on this particular date, How to get in this format 28 years, 2 months, and 21 days? My D.O.B input will be in this format DD/MM/YYYY.

• So you want to define a command that takes your D.O.B. in dd/mm/yyyy format as input and returns your age in dd/mm/yyyy based on \today? Commented May 23, 2017 at 16:46
• Yes you are corecct @Karlo Commented May 23, 2017 at 16:47
• To be pedantic, I don't think that what you are asking for is well defined! For example two consecutive months can be either 59, 60, 61 or 62 days. So 28 years, 2 months, and 21 days will mean different things depending on the starting date. It's is true that you can "calculate" a date that is 28 years, 2 months, and 21 days from a given date but the time between these dates will change with your starting date.
– user30471
Commented May 24, 2017 at 1:19
• Thanks for information, i have corrected my question@Andrew Commented May 24, 2017 at 2:25

I took percusse's idea and jumped down the rabbit hole, sort of. However, it certainly doesn't account for any Gregorian/Julian manipulations and, most importantly, it will print an asterisk following the day, when it must assume there are 30 days in the month.

But let's face it, the format of years, months, and days is intrinsically ambiguous. One can certainly tell me how many days it is from 24 April to 23 May, but I argue you cannot tell me how many months and days it is from 24 March to 23 May. It depends on whether I am counting the month as 24 Mar to 24 April and then count the leftover days versus counting the month as 23 April to 23 May and then count the leftover days.

\documentclass{article}
\usepackage{listofitems}
\newcommand\getage[1]{%
\setsepchar[,]{/}%
\edef\agedays{\the\numexpr\the\day-\starting[1]\relax}%
\edef\agemonths{\the\numexpr\the\month-\starting[2]\relax}%
\edef\ageyears{\the\numexpr\the\year-\starting[3]\relax}%
\ifnum\agedays<0\relax
\edef\agemonths{\the\numexpr\agemonths-1\relax}%
\edef\agedays{\the\numexpr\agedays+30\relax*}%
\fi
\ifnum\agemonths<0\relax
\edef\ageyears{\the\numexpr\ageyears-1\relax}%
\edef\agemonths{\the\numexpr\agemonths+12\relax}%
\fi
From #1 to \the\day/\the\month/\the\year{} is
\ageyears{} years, \agemonths{} months, and \agedays{} days.%
}

\begin{document}
\getage{10/02/1989}

\getage{10/07/1989}

\getage{23/07/1989}

\getage{24/07/1989}
\end{document}


Here, I go a step further and calculate days, assuming I count days from the most recent month before the end date. Note that this is, if you will, defining how months + days are counted. So it avoids ambiguity only by definition. And it still does not account for leap years, and so any calculation that ends in March of a leap year for which the starting \day exceeds the ending \day will be off by 1 day. EDITED to flag calculations with a trailing \dag which may be subject to the leap year error.

REEDITED to allow ending date to be supplied as optional argument (default \today).

\documentclass{article}
\usepackage{listofitems}
\newcommand\getage[2][\relax]{\bgroup%
\setsepchar[,]{/}%
\ifx\relax#1\relax\else
\day=\ending[1]\relax%
\month=\ending[2]\relax%
\year=\ending[3]\relax%
\fi%
\xdef\agedays{\the\numexpr\the\day-\starting[1]\relax}%
\xdef\agemonths{\the\numexpr\the\month-\starting[2]\relax}%
\xdef\ageyears{\the\numexpr\the\year-\starting[3]\relax}%
\ifnum\agedays<0\relax
\monthlength{\the\month}%
\xdef\agemonths{\the\numexpr\agemonths-1\relax}%
\xdef\agedays{\the\numexpr\agedays+\themonthlength\relax}%
\fi
\ifnum\agemonths<0\relax
\xdef\ageyears{\the\numexpr\ageyears-1\relax}%
\xdef\agemonths{\the\numexpr\agemonths+12\relax}%
\fi
From #2 to \the\day/\the\month/\the\year{} is
\ageyears{} years, \agemonths{} months, and \agedays{} days%
\ifnum\month=3\relax\ifnum\starting[1]>\day\relax$^{\dag}$\fi\fi.%
\egroup}
\newcommand\monthlength[1]{%
\edef\themonthlength{%
% PRIOR MONTH:    DEC  JAN  FEB  MAR  APR  MAY  JUN  JUL  AUG  SEP  OCT  NOV
\ifcase#1 xx\or31\or31\or28\or31\or30\or31\or30\or31\or31\or30\or31\or30\fi%
}%
}
\begin{document}
\getage{10/02/1989}\par
\getage{10/07/1989}\par
\getage{23/07/1989}\par
\getage{24/07/1989}\par
\getage{24/04/2017}\par
\getage{24/03/2017}\par
\getage[23/3/2017]{24/02/2017}\par
\getage[23/11/2017]{24/10/2017}\par
\getage[01/05/2017]{10/02/1989}
\end{document}


• Total number of days for July is 31 and Total number of days for August is 31@Steven B. Segletes Commented May 23, 2017 at 22:07
• Condition you have taken for non-leap year , what about for leap year?@Steven B. Segletes Commented May 24, 2017 at 2:18
• @BikiTeron As I said in the text of the answer, results flagged with \dag will need to add 1 day if the ending year is a leap year. Commented May 24, 2017 at 2:33
• ok that means \dag will take the resposibility for leap year@Steven B. Segletes Commented May 24, 2017 at 2:36
• @BikiTeron Yes, if it is a leap year. Alternately, if one could test \the\year for leap-year-edness, then just add 1 to \agedays if leap-year-edness is true and the \dag condition is true. Commented May 24, 2017 at 2:43

I can give you the number of days but I'm not going down that rabbit hole of converting into years, months, days depending on when and where this is happening.

EDIT: Local change stuff, just to avoid making package authors angry...

\documentclass{article}
\usepackage{pgfkeys,pgfcalendar}

\makeatletter
\def\mydatediff#1{%
\begingroup%
\pgfcalendardatetojulian{#1}{\@tempcnta}%
\pgfcalendardatetojulian{\year-\month-\day}{\@tempcntb}%