![如何以年、月、日格式计算特定日期的年龄?](https://linux22.com/image/355470/%E5%A6%82%E4%BD%95%E4%BB%A5%E5%B9%B4%E3%80%81%E6%9C%88%E3%80%81%E6%97%A5%E6%A0%BC%E5%BC%8F%E8%AE%A1%E7%AE%97%E7%89%B9%E5%AE%9A%E6%97%A5%E6%9C%9F%E7%9A%84%E5%B9%B4%E9%BE%84%EF%BC%9F.png)
假设我的出生日期是 1989 年 10 月 2 日,我想计算我在 2017 年 5 月 1 日的年龄,那么我在这一天的年龄就是 28 岁 2 个月 21 天。如何以 28 岁 2 个月 21 天的格式计算出生日期?我的出生日期输入格式为 DD/MM/YYYY。
答案1
我采纳了 percusse 的想法,并跳进了兔子洞,有点像。然而,它肯定没有考虑到任何公历/儒略历操作,最重要的是,它会在日期后面打印一个星号,而这是必须的认为这个月有 30 天。
但让我们面对现实吧,年、月和日的格式本质上是模棱两可的。人们当然可以告诉我从 4 月 24 日到 5 月 23 日有多少天,但我认为你无法告诉我从 3 月 24 日到 5 月 23 日有多少个月和多少天。这取决于我是否将月份计算为 3 月 24 日至 4 月 24 日,然后计算剩余的天数相对将月份计算为 4 月 23 日至 5 月 23 日,然后计算剩余的天数。
\documentclass{article}
\usepackage{listofitems}
\newcommand\getage[1]{%
\setsepchar[,]{/}%
\readlist\starting{#1}%
\edef\agedays{\the\numexpr\the\day-\starting[1]\relax}%
\edef\agemonths{\the\numexpr\the\month-\starting[2]\relax}%
\edef\ageyears{\the\numexpr\the\year-\starting[3]\relax}%
\ifnum\agedays<0\relax
\edef\agemonths{\the\numexpr\agemonths-1\relax}%
\edef\agedays{\the\numexpr\agedays+30\relax*}%
\fi
\ifnum\agemonths<0\relax
\edef\ageyears{\the\numexpr\ageyears-1\relax}%
\edef\agemonths{\the\numexpr\agemonths+12\relax}%
\fi
From #1 to \the\day/\the\month/\the\year{} is
\ageyears{} years, \agemonths{} months, and \agedays{} days.%
}
\begin{document}
\getage{10/02/1989}
\getage{10/07/1989}
\getage{23/07/1989}
\getage{24/07/1989}
\end{document}
在这里,我更进一步计算天数,假设我从结束日期前最近的一个月开始计算天数。请注意,如果您愿意的话,这是定义如何计算月份 + 天数。因此,它只是通过定义来避免歧义。而且它仍然不考虑闰年,因此任何在闰年三月结束的计算,如果开始时间\day
超过结束时间,\day
则会偏离 1 天。已编辑以标记带有尾随的计算\dag
计算可能可能会受到闰年误差的影响。
REEDITED 允许提供结束日期作为可选参数(默认\today
)。
\documentclass{article}
\usepackage{listofitems}
\newcommand\getage[2][\relax]{\bgroup%
\setsepchar[,]{/}%
\ifx\relax#1\relax\else
\readlist\ending{#1}%
\day=\ending[1]\relax%
\month=\ending[2]\relax%
\year=\ending[3]\relax%
\fi%
\readlist\starting{#2}%
\xdef\agedays{\the\numexpr\the\day-\starting[1]\relax}%
\xdef\agemonths{\the\numexpr\the\month-\starting[2]\relax}%
\xdef\ageyears{\the\numexpr\the\year-\starting[3]\relax}%
\ifnum\agedays<0\relax
\monthlength{\the\month}%
\xdef\agemonths{\the\numexpr\agemonths-1\relax}%
\xdef\agedays{\the\numexpr\agedays+\themonthlength\relax}%
\fi
\ifnum\agemonths<0\relax
\xdef\ageyears{\the\numexpr\ageyears-1\relax}%
\xdef\agemonths{\the\numexpr\agemonths+12\relax}%
\fi
From #2 to \the\day/\the\month/\the\year{} is
\ageyears{} years, \agemonths{} months, and \agedays{} days%
\ifnum\month=3\relax\ifnum\starting[1]>\day\relax$^{\dag}$\fi\fi.%
\egroup}
\newcommand\monthlength[1]{%
\edef\themonthlength{%
% PRIOR MONTH: DEC JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV
\ifcase#1 xx\or31\or31\or28\or31\or30\or31\or30\or31\or31\or30\or31\or30\fi%
}%
}
\begin{document}
\getage{10/02/1989}\par
\getage{10/07/1989}\par
\getage{23/07/1989}\par
\getage{24/07/1989}\par
\getage{24/04/2017}\par
\getage{24/03/2017}\par
\getage[23/3/2017]{24/02/2017}\par
\getage[23/11/2017]{24/10/2017}\par
\getage[01/05/2017]{10/02/1989}
\end{document}
答案2
我可以告诉你天数,但我不会根据事情发生的时间和地点去把它转换成年、月、天。
编辑:本地更改内容,只是为了避免让包作者生气......
\documentclass{article}
\usepackage{pgfkeys,pgfcalendar}
\makeatletter
\def\mydatediff#1{%
\begingroup%
\pgfcalendardatetojulian{#1}{\@tempcnta}%
\pgfcalendardatetojulian{\year-\month-\day}{\@tempcntb}%
\advance\@tempcntb-\@tempcnta\relax%
\expandafter\aftergroup\the\@tempcntb%
\endgroup%
}
\begin{document}
\mydatediff{2007-01-14}...
\end{document}