The datenumber
package allows you to calculate date differences and return the difference as number of days. You still need to make years and month out of it.
Starting of the example \daydifftoday
in the manual:
\documentclass{article}
\usepackage{datenumber}
\newcounter{dateone}
\newcounter{datetwo}
\newcommand{\difftoday}[3]{%
\setmydatenumber{dateone}{\the\year}{\the\month}{\the\day}%
\setmydatenumber{datetwo}{#1}{#2}{#3}%
\addtocounter{datetwo}{-\thedateone}%
\the\numexpr-\thedatetwo/365\relax\space year(s),
\the\numexpr(-\thedatetwo - (-\thedatetwo/365)*365)/30\relax\space month(s)
}
\begin{document}
\difftoday{2010}{02}{01}
\end{document}
This code could be further refined to check if the difference is less than a year, one year or more than one year to display "year(s)" accordantly. The same counts for the month:
\documentclass{article}
\usepackage{datenumber}
\usepackage{calc}
\newcounter{datetoday}
\newcounter{diffyears}
\newcounter{diffmonths}
\newcounter{diffdays}
\newcommand{\difftoday}[3]{%
\setmydatenumber{datetoday}{\the\year}{\the\month}{\the\day}%
\setmydatenumber{diffdays}{#1}{#2}{#3}%
\addtocounter{diffdays}{-\thedatetoday}%
\ifnum\value{diffdays}>0
\def\diffbefore{in }%
\def\diffafter{}%
\else
\def\diffbefore{}%
\def\diffafter{ago}%
\setcounter{diffdays}{-\value{diffdays}}%
\fi
\setcounter{diffyears}{\value{diffdays}/365}%
\setcounter{diffdays}{\value{diffdays}-365*\value{diffyears}}%
\setcounter{diffmonths}{\value{diffdays}/30}%
\setcounter{diffdays}{\value{diffdays}-30*\value{diffmonths}}%
%
\diffbefore
\ifnum\value{diffyears}=0
\else
\ifnum\value{diffyears}>1
\thediffyears\space years,
\else
\thediffyears\space year,
\fi
\fi
\ifnum\value{diffmonths}=0
\else
\ifnum\value{diffmonths}>1
\thediffmonths\space months
\else
\thediffmonths\space month
\fi
\fi
\diffafter
}
\begin{document}
\difftoday{2011}{02}{01}
\difftoday{2010}{02}{01}
\difftoday{2009}{02}{01}
\difftoday{2009}{01}{01}
\difftoday{2012}{02}{01}
\difftoday{2012}{12}{01}
\end{document}
This gives:
1 month ago
1 year, 1 month ago
2 years, 1 month ago
2 years, 2 months ago
in 10 months
in 1 year, 8 months
This should be fine when the accuracy is months (which are taken as 30 days each). Exact days would require to take the different number of days per month and leap years into account.
Note the \diffbefore
and \diffafter
macros. You can adjust them to your liking and/or language.
Using \pgfmathtruncatemacro
makes the trick.
\documentclass{standalone}
\usepackage{amsmath,tikz}
\usetikzlibrary{arrows,calc}
\begin{document}
\begin{tikzpicture}
\def \currentYear {2016}
\def \n {4}
\foreach \i in {0,...,\n}
{
\pgfmathtruncatemacro{\nextYear}{\currentYear + \i}
\node (N) at (\i,\i) {\nextYear};
}
\end{tikzpicture}
\end{document}
Best Answer
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.
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
).