Есть ли простой способ вычислить разницу между двумя временами (один и тот же день), так что 11:30 утра и 01:20 дня должны дать 110 минут (или 1 час 50 минут), например? Я видел пакет, datenumber
но он, похоже, вычисляет только разницу дней (так что работает в большем масштабе). [Я не включил минимальный пример, поскольку у меня нет элегантного способа начать задачу, кроме (уродливых?) подходов «разделяй и властвуй»]
Ладно, я только что также обнаружил, datetime
что выглядит более многообещающе. Тем не менее, я не вижу, как можно вычислить разницу временных точек с помощью этого пакета (или calc
?)
Обновлять
После ответа Дэвида я расширил MWE до своего исходного примера и обнаружил следующую Runaway argument
проблему:
\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}
Как этого можно избежать? [еще одна пара {}
не помогла]
решение1
\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}
Если вы хотите развернуть аргументы перед синтаксическим анализом, как в отредактированном 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}
решение2
Развивая превосходный ответ Дэвида, дадим альтернативный вывод, как
xx hour(s) xx minute(s)
.
ПЕРЕИЗДАНО для использования единственного числа «минута» и «час», если их только 1. Также применено исправление по модулю, когда время было 12:xx (пришлось вычесть 720, чтобы обработать 12 часов как 00 часов)
Вот MWE (ОТРЕДАКТИРОВАНО с целью расширения аргументов и возможности их передачи в форме макроса):
\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}