# How to compute the difference between two time points (e.g., 11:30 am and 01:20 pm => 110 min)?

Is there a simple way to compute the difference between two times (same day), so 11:30 am and 01:20 pm should lead to 110 min (or 1h 50min), for example? I saw the datenumber package but it only seems to compute day differences (so works on a larger scale). [I didn't include a minimal example as I don't have any elegant way how to start the problem except for (ugly?) string 'divide-and-conquer' approaches]

Okay, I just also discovered datetime which looks more promising. Nevertheless, I don't see how one can compute differences of time points with this package (or calc?)

Update After David's answer, I expanded the MWE to my original example and realized the following Runaway argument-problem:

\documentclass{article}

\newcommand*{\mystart}{11:30 am}
\newcommand*{\myend}{01:20 pm}

% duration
\def\duration#1#2{%
\the\numexpr(\xduration#2\relax)-(\xduration#1\relax)\relax\ minutes}

\def\xduration#1:#2 #3m#4\relax{%
(#1)*60+#2\if p#3+720 \fi
}

% environment
\newenvironment{tbl}[3]{
\begin{tabular}{ll}
#1 & \duration{#2}{#3}\\
\end{tabular}
}{}

\begin{document}
\begin{tbl}{Duration}{\mystart}{\myend}% Runaway argument? ! File ended while scanning use of \xduration.
%\begin{tbl}{Duration}{11:30 am}{01:20 pm}% works
\end{tbl}
\end{document}

How can this be avoided? [another pair of {} did not help]

• Do you want the difference result as "110 minutes" or "1 hr 50 minutes"? – Steven B. Segletes Sep 25 '14 at 13:09
• Convert the hour to minutes: (hour if pm + 12 fi)*60 + minutes; do the difference; convert back to hour and minutes. – egreg Sep 25 '14 at 13:13
• @StevenB.Segletes Thanks, both are okay, whatever is more convenient. – Marius Hofert Sep 25 '14 at 13:18
• To fix your problem, replace \xduration with \expandafter\xduration in the definition of \duration. (twice) – Steven B. Segletes Sep 25 '14 at 14:03

\documentclass{article}

\def\foo#1#2{%
\the\numexpr(\xfoo#2\relax)-(\xfoo#1\relax)\relax\ minutes}

\def\xfoo#1:#2 #3m#4\relax{%
%(#1)*60+#2\if p#3+720 \fi
(#1)*60+#2\if p#3\ifnum#1=12 \else+720\fi\fi
}

\begin{document}

\foo{11:30 am}{01:20 pm}

\end{document}

If you want to expand the arguments before parsing, as in the edited MWE:

\documentclass{article}

\newcommand*{\mystart}{11:30 am}
\newcommand*{\myend}{01:20 pm}

% duration
\def\duration#1#2{%
{\def\,{ }%
\edef\tmp{%
\noexpand\theminutes{%
\noexpand\the
\noexpand\numexpr
(\noexpand\xduration#2\relax)-%
(\noexpand\xduration#1\relax)\relax}}\tmp}}

\def\xduration#1:#2 #3m#4\relax{%
%(#1)*60+#2\if p#3+720\fi
(#1)*60+#2\if p#3\ifnum#1=12 \else+720\fi\fi
}

\def\theminutes#1{%
#1\ minute\ifnum#1=1 \else s\fi}

% environment
\newenvironment{tbl}[3]{
\begin{tabular}{ll}
#1 & \duration{#2}{#3}\\
\end{tabular}
}{}

\begin{document}
\begin{tbl}{Duration}{11:30 am}{01:20 pm}% works
\end{tbl}

\begin{tbl}{Duration}{\mystart}{\myend}% Runaway argument? ! File ended while scanning use of \xduration.
\end{tbl}

\begin{tbl}{Duration}{11:30\,am}{01:20\,pm}% works
\end{tbl}

\begin{tbl}{Duration}{12:30 pm}{03:00 pm} % works
\end{tbl}

\begin{tbl}{Duration}{11:30\,am}{11:31\,am}
\end{tbl}

\end{document}

• I realized a strange error when I use the "duration" command inside a table/environment. I updated the post. Do you see how to avoid this error? – Marius Hofert Sep 25 '14 at 13:57
• @MariusHofert nothing to do with tabular, I parse looking for : to split up the time and you hid that in a macro, if you need to expand macros before parsing for minutes it needs another line... – David Carlisle Sep 25 '14 at 14:04
• Hi, thanks a lot, David. I just had to put a % after \edef\tmp{ to avoid a small horizontal space to be inserted. Works very well, thanks again. – Marius Hofert Sep 25 '14 at 14:10
• @MariusHofert updated answer – David Carlisle Sep 25 '14 at 22:10
• @SvendTveskæg updated – David Carlisle Nov 15 '14 at 16:08

Expanding on David's excellent answer, to give the alternative output, as

xx hour(s) xx minute(s).

REEDITED to use singular "minute" and "hour" if there is only 1 of them. Also, applied modulo fix when time was 12:xx (had to subtract 720 to treat 12 hour like 00 hour)

Here is the MWE (EDITED to expand the arguments, allowing them to be passed in macro form):

\documentclass{article}

\def\foo#1#2{\edef\tmp{\numfoo{#1}{#2}}\tmp\ minute%
\ifnum\tmp=1\relax\else s\fi}

\def\xfoo#1:#2 #3m#4\relax{(#1)*60+#2\if p#3+720\fi\ifnum#1=12-720\fi}

\def\numfoo#1#2{%
\the\numexpr(\expandafter\xfoo#2\relax)-(\expandafter\xfoo#1\relax)\relax}

\def\barr#1#2{%
\edef\tmp{\the\numexpr((\numfoo{#1}{#2})-(30))/60\relax}%
\tmp\ hour\ifnum\tmp=1\relax\else s\fi\ %
\edef\tmp{\the\numexpr(\numfoo{#1}{#2})-((\numfoo{#1}{#2})-(30))/60*60}%
\tmp\ minute\ifnum\tmp=1\relax\else s\fi%
}

\begin{document}
\foo{11:30 am}{01:20 pm} = \barr{11:30 am}{01:20 pm}

\foo{11:30 am}{12:31 pm} = \barr{11:30 am}{12:31 pm}

\foo{12:30 am}{12:31 pm} = \barr{12:30 am}{12:31 pm}

\foo{11:59 am}{12:00 pm} = \barr{11:59 am}{12:00 pm}

\def\starttime{11:30 am}
\def\endtime{03:20 pm}

\foo{\starttime}{\endtime} = \barr{\starttime}{\endtime}
\end{document}

• Is it possible to use some sort of \if argument to get hour if it's 1 and hours if it's anything else? (The same with minute/minutes.) – Svend Tveskæg Nov 15 '14 at 15:47
• @SvendTveskæg Done, and fixed bug when time involved "12:xx" – Steven B. Segletes Nov 15 '14 at 20:19