# How to make time-dependent code?

I would like to create a command \ifafter{year}{month}{day}{yes}{no} so that if the current date is after year/month/day, the command would produce yes, and otherwise produce no.

I came up with a solution, and I wanted to document it as well as see other solutions. Natural generalizations, e.g. a version that compares the current time with hour : minute : second, a version that checks whether year/month/day is further than x days in the future (or past), etc., would also be welcomed.

-

The same result can be obtained without any package:

\makeatletter
\newcommand\ifafter[3]{%
\ifnum\the\year\two@digits\month\two@digits\day >
\numexpr#1\two@digits{#2}\two@digits{#3}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}
\makeatother


We can also encode the date as "year*10000+month*100+day", so the test can be

\makeatletter
\newcommand\ifafter[3]{%
\ifnum\numexpr\year*10000+\month*100+\day\relax
>\numexpr#1*10000+#2*100+#3\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}
\makeatother


Or, with etoolbox and datetime, without an auxiliary counter:

\newcommand{\ifafter}[5]{%
\ifnumgreater
{\the\year\twodigit{\the\month}\twodigit{\the\day}}
{#1\twodigit{#2}\twodigit{#3}}
{#4}
{#5}%
}


The relevant thing here is that TeX continues to expand tokens when it is looking for a number. My definitions allow also

\ifafter{2012}{1}{16}{Yes, it is after Jan. 16, 2012.}{No, it is not after Jan. 16, 2012.}


Your macro would be unsuccessful on Jan. 17, 2012 with

\ifafter{2012}{2}{1}{after}{not after}


as the comparison would be between 20120117 and 201221. Using \twodigit both for today's date and the user input guarantees correct result even when the user is lazy.

And the LaTeX3 version:

\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\ifafter}{ m m m }
{
\int_compare:nTF
{ \year*10000+\month*100+\day > #1*10000+#2*100+#3 }
}
\ExplSyntaxOff

-
Fantastic! :) –  Paulo Cereda Jan 18 '12 at 11:05

You can use the date registers \year, \month and \day which hold the current year, month and day as integers. If you put \the in front of them they expand to the number, which is important if you want to concatenate these numbers.

You can use the \ifnum primitive to compare two integers. You need however add a 0 if the month or day is lower than 10:

\documentclass{article}
\makeatletter
\newcommand{\ifafter}[3]{%
\ifnum#1#2#3<\the\year\ifnum\month<10 0\fi\the\month\ifnum\day<10 0\fi\the\day\space
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\makeatother
\begin{document}
\ifafter{2012}{01}{16}{After 16th Jan 2012.}{Before 16th Jan 2012.}

\ifafter{2012}{01}{17}{After 17th Jan 2012.}{Before 17th Jan 2012.}

\ifafter{2012}{01}{18}{After 18th Jan 2012.}{Before 18th Jan 2012.}
\end{document}


This does not require any package nor e-TeX.

For anything more complex I can recommend the datenumber package which allows to calculate the difference in days between two dates. See the \daydifftoday example at the back of the package manual.

-

Here is the solution I came up with. Compiling the following code today (Jan. 17, 2012),

\documentclass{article}
\usepackage{etoolbox,datetime}
\newcommand{\twodigitday}{\twodigit{\the\day}}
\newcommand{\twodigitmonth}{\twodigit{\the\month}}
\newcounter{mydatenum}
\setcounter{mydatenum}{\the\year\twodigitmonth\twodigitday}
\newcommand{\ifafter}[5]{\ifnumgreater{\arabic{mydatenum}}{#1#2#3}{#4}{#5}}
\begin{document}
\ifafter{2012}{01}{16}{Yes, it is after Jan. 16, 2012.}{No, it is not after Jan. 16, 2012.}
\ifafter{2012}{01}{17}{Yes, it is after Jan. 17, 2012.}{No, it is not after Jan. 17, 2012.}
\end{document}


produces

-