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

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[,]{/}%
  \readlist\starting{#1}%
  \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}

enter image description here

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
    \readlist\ending{#1}%
    \day=\ending[1]\relax%
    \month=\ending[2]\relax%
    \year=\ending[3]\relax%
  \fi%
  \readlist\starting{#2}%
  \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}

enter image description here


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}%
\advance\@tempcntb-\@tempcnta\relax%
\expandafter\aftergroup\the\@tempcntb%
\endgroup%
}
\begin{document}
\mydatediff{2007-01-14}... 
\end{document}

Tags:

Calculations