¿Existe una forma sencilla de calcular la diferencia entre dos horas (el mismo día), de modo que las 11:30 a. m. y las 01:20 p. m. deberían dar lugar a 110 min (o 1 h 50 min), por ejemplo? Vi el datenumber
paquete pero parece que solo calcula las diferencias de días (por lo que funciona a mayor escala). [No incluí un ejemplo mínimo porque no tengo ninguna forma elegante de comenzar el problema, excepto los (¿feos?) enfoques de cadena de 'divide y vencerás']
Bien, también descubrí datetime
cuál parece más prometedor. Sin embargo, no veo cómo se pueden calcular las diferencias de puntos de tiempo con este paquete (¿o calc
?)
Actualizar
Después de la respuesta de David, amplié el MWE a mi ejemplo original y me di cuenta del siguiente Runaway argument
problema:
\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}
¿Cómo puede esto ser evitado? [otro par de {}
no ayudó]
Respuesta1
\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}
Si desea expandir los argumentos antes del análisis, como en el MWE editado:
\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}
Respuesta2
Ampliando la excelente respuesta de David, para brindar el resultado alternativo, como
xx hour(s) xx minute(s)
.
REEDITADO para usar "minuto" y "hora" en singular si solo hay 1 de ellos. Además, se aplicó la corrección de módulo cuando el tiempo era 12:xx (tuve que restar 720 para tratar 12 horas como 00 horas)
Aquí está el MWE (EDITADO para expandir los argumentos, permitiendo pasarlos en forma de macro):
\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}