summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2012-09-18 23:42:21 +0000
committerKarl Berry <karl@freefriends.org>2012-09-18 23:42:21 +0000
commit7d3fe67946edf779c9af7cf56549b46e86255fe1 (patch)
treeea7d01bb0b6f8dc5825f4c2025a0bd5a5b5b4215
parente5b88ab6891e9bb2dc1ac846e942f5bf4e21dfe0 (diff)
new latex package calcage (18sep12)
git-svn-id: svn://tug.org/texlive/trunk@27725 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/latex/calcage/README34
-rw-r--r--Master/texmf-dist/doc/latex/calcage/calcage.pdfbin0 -> 279088 bytes
-rw-r--r--Master/texmf-dist/source/latex/calcage/calcage.dtx412
-rw-r--r--Master/texmf-dist/source/latex/calcage/calcage.ins23
-rw-r--r--Master/texmf-dist/tex/latex/calcage/calcage.sty80
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rw-r--r--Master/tlpkg/tlpsrc/calcage.tlpsrc0
-rw-r--r--Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc1
8 files changed, 551 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/calcage/README b/Master/texmf-dist/doc/latex/calcage/README
new file mode 100644
index 00000000000..c8cf3439324
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/calcage/README
@@ -0,0 +1,34 @@
+LaTeX package 'calcage'
+~~~~~~~~~~~~~~~~~~~~~~~~
+Copyright (C) 2012 by Robin Schneider <ypid23@aol.de>
+
+This work may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3
+of this license or (at your option) any later version.
+The latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+CTAN: http://www.ctan.org/pkg/calcage
+Code repository: https://github.com/ypid/latex-packages/tree/master/calcage
+
+
+ DESCRIPTION
+Calculates the age in years
+
+The calcage package can calculate the age of someone or something in years.
+Internally it uses the datenumber package to calculate the age in days. The
+conversion from days to years is implemented by this package. It is also taken
+care about leap years and such odd things.
+
+ GENERATING THE FILES
+You can generate the calcage.sty file with: pdflatex calcage.ins
+
+The documentation can be generated with:
+pdflatex calcage.dtx
+makeindex -s gglo.ist -o calcage.gls calcage.glo
+makeindex -s gind calcage
+pdflatex calcage.dtx
+thumbpdf calcage
+pdflatex calcage.dtx
diff --git a/Master/texmf-dist/doc/latex/calcage/calcage.pdf b/Master/texmf-dist/doc/latex/calcage/calcage.pdf
new file mode 100644
index 00000000000..4667f2f2f2c
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/calcage/calcage.pdf
Binary files differ
diff --git a/Master/texmf-dist/source/latex/calcage/calcage.dtx b/Master/texmf-dist/source/latex/calcage/calcage.dtx
new file mode 100644
index 00000000000..e01764d9bda
--- /dev/null
+++ b/Master/texmf-dist/source/latex/calcage/calcage.dtx
@@ -0,0 +1,412 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2012 by Robin Schneider <ypid23@aol.de>
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Robin Schneider.
+%
+% This work consists of the files calcage.dtx and calcage.ins
+% and the derived filebase calcage.sty.
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\ProvidesFile{calcage.dtx}
+%</driver>
+%<package>%% See file 'calcage.dtx' for copyright and licence.
+%<package>\NeedsTeXFormat{LaTeX2e}[1998/12/01]
+%<package>\ProvidesPackage{calcage}
+%<*package>
+ [2012/09/09 v0.90 Calculate the age in years]
+%</package>
+%
+%<*driver>
+\documentclass[english]{ltxdoc}
+\newcommand{\PackageURL}{https://github.com/ypid/latex-packages/tree/master/calcage}
+\newcommand{\PackageCTANURL}{http://www.ctan.org/pkg/calcage}
+\newcommand{\PackageAuthor}{Robin Schneider}
+\newcommand{\PackageAuthorEmail}{ypid23@aol.de}
+\newcommand{\PackageName}{\PrintPackage{calcage}}
+\newcommand{\PrintPackage}[1]{\textsf{#1}}
+\newcommand{\PrintOptionF}[1]{\emph{#1}} %% ^^A This macro is used for
+%% ^^A explaining any parameter when they first come up in the documentation.
+\newcommand{\DescribePara}[1]{\marginpar{\raggedleft\strut\MacroFont\string #1}}
+\usepackage{calcage}
+\usepackage{
+ babel,
+ csquotes,
+ xcolor,
+ url,
+ hypdoc,
+ nameref,
+}
+\GetFileInfo{calcage.dtx}
+\hypersetup{
+ pdftitle={A manual for \PackageName},
+ pdfauthor={\PackageAuthor{} <\PackageAuthorEmail>},
+ pdfsubject={\fileinfo},
+ baseurl={\PackageURL},
+ pdfkeywords={This document corresponds to \PackageName~\fileversion,
+ dated \filedate}
+}
+
+\title{The \PackageName{} package\thanks{This document
+corresponds to \PackageName~\fileversion, dated \filedate.}}
+\author{\PackageAuthor \\
+ \texttt{\href{mailto:\PackageAuthorEmail?subject=LaTeX package calcage}%
+ {\PackageAuthorEmail}%
+ }%
+}
+
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\begin{document}
+ \DocInput{calcage.dtx}
+ \PrintChanges
+ \PrintIndex
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{122}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+% \changes{0.90}{2012/09/09}{Initial version}
+%
+% \DoNotIndex{\RequirePackage, \DeclareOption, \ProcessOptions}
+% \DoNotIndex{\PackageWarning, \MessageBreak}
+% \DoNotIndex{\DeclareRobustCommand, \newcommand, \renewcommand, \def, \edef}
+% \DoNotIndex{\DeclareStringOption, \ProcessLocalKeyvalOptions}
+% \DoNotIndex{\ProcessKeyvalOptions, \SetupKeyvalOptions, \DeclareBoolOption}
+% \DoNotIndex{\newenvironment}
+% \DoNotIndex{\if, \else, \fi, \ifcase, \or, \ifthenelse, \AND, \OR, \value, \relax}
+% \DoNotIndex{\loop, \repeat, \the, \ifnum}
+% \DoNotIndex{\equal, \boolean, \@currname, \newcounter, \setcounter}
+% \DoNotIndex{\stepcounter, \addtocounter}
+% \DoNotIndex{\endinput}
+%
+% \maketitle
+%
+% \phantomsection
+% \addcontentsline{toc}{section}{\abstractname}
+% \begin{abstract}
+% The \PackageName{} package can calculate the age in years. \\
+% Information site on CTAN: \url{\PackageCTANURL} \\
+% Fork me on GitHub: \url{\PackageURL} \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Introduction}
+% The \PrintPackage{calcage} package can calculate the age of someone or
+% something in years. Internally it uses the \PrintPackage{datenumber} package
+% to calculate the age in days. The conversion from days to years is
+% implemented by this package. It is also taken care about leap years and such
+% odd things. So if you enter your birthday you get your exact age in years.
+% You can even get the age as number with up to 18 places after the decimal
+% separator but I heard that this is a bit uncommon for the age of a person~\dots
+%
+% \section{Usage}
+% Just load the package placing
+% \begin{quote}
+% |\usepackage{calcage}|
+% \end{quote}
+% in the preamble of your \LaTeXe{} source file.
+%
+% You can also give optional package options to change the default behavior.
+% But you can not give values (see \nameref{sec:bugs}). So
+% \begin{quote}
+% |\usepackage[presision]{calcage}|
+% \end{quote}
+% works and sets the presision to 3. But \enquote{presision=3} is going to
+% fail~\dots
+% \bigskip
+%
+% \DescribeMacro{\calcage}
+% The macro |\calcage| \oarg{optional parameters} \marg{year} \marg{month}
+% \marg{day} takes a date and typesets the difference to the current date in
+% years.
+% \bigskip
+%
+% There are some optional parameters. \DescribePara{year, month, day} For
+% example you can adjust the current date for \PrintPackage{calcage} with the
+% keys \enquote{\PrintOptionF{year}}, \enquote{\PrintOptionF{month}} and
+% \enquote{\PrintOptionF{day}}. You don't have to specifier all of them. A
+% subset is also possible.
+%
+% Another useful parameter is \enquote{\PrintOptionF{precision}}.
+% \DescribePara{precision} With this parameter you can specify how many places
+% after the decimal separator you would like to get. The default precision is 0
+% which means that |\calcage| will typeset the age in years as integer. If you
+% omit a value for \enquote{precision} then the precision will be 3.
+%
+% The macro |\calcage| can also take a date which is in the future.
+% \DescribePara{positive} The default behavior in this case is a negative
+% number but you can make the number positive with the
+% \enquote{\PrintOptionF{positive}} boolean switch.
+%
+% The next parameter I would like to show you is the \DescribePara{printyear}
+% \enquote{\PrintOptionF{printyear}} boolean switch. With this switch you can
+% specify if |\calcage| should add \enquote{year} or rather \enquote{years}
+% after the age. This is the default setting.
+%
+%
+% For the previous parameter you may need the possibility
+% \DescribePara{yearsuffix} (at least in the German language) to add a single
+% character to the plural word. For example
+% \begin{quote}
+% |Albert Einstein wurde vor \calcage[yearsuffix]{1879}{03}{14}| \\
+% |geboren.| \\
+% Albert Einstein wurde vor \calcage[printyear=false]{1879}{03}{14} Jahren geboren.
+% ^^A Ups you got my. I didn't implement a switch language feautre (yet).
+% \end{quote}
+% To do this you can use the boolean switch
+% \enquote{\PrintOptionF{yearsuffix}}. By default this switch is false.
+% If this boolean is true and the German language was selected then a
+% \enquote{n} will be added after \enquote{Jahre}. If the English language was
+% selected then this switch will not change the output.
+%
+% And last but not least there is the boolean switch \enquote{numberstring}
+% \DescribePara{numberstring} which is true by default. This means that the
+% typesetting process of an integer is done by the package
+% \PrintPackage{fnumprint} which will typeset the word of a number instead of
+% the Arabic number if the value of the number is between 0 and 12. If you
+% don't like this behavior you can set the boolean to false with
+% \enquote{numberstring=false}.
+%
+% \section{Bugs}\label{sec:bugs}
+% I tried to implement the possibility to change the default behavior as
+% package option in a nice way but with the current implementation there is a
+% problem with the values. If you give a key with value then the |\setkeys|
+% macro which gets these parameters as macro fails. I already tried
+% |\expandafter| so if anyone knows where the problem is or has a solution feel
+% free to contact me.
+% \bigskip
+%
+% I think there is a little inaccuracy in the conversion from days to years
+% because my implementation just removes the leap years before dividing. But in
+% my tests this seems to be more theoretically.
+%
+% The problem only has an effect if leap years are involved because if a leap
+% year is calculated then the additional day is subtracted. This means that one
+% day is not longer $\frac{1}{366}$ year but $\frac{1}{365}$ year~\dots
+%
+% \section{Examples}
+% \begin{verbatim}
+% \TeX{} Live realeases: \\
+% \calcage{2012}{07}{08} \\
+% \calcage{2011}{07}{20} \\
+% \calcage{2010}{09}{10} \\
+% \calcage{2009}{11}{09}
+% \end{verbatim}\vspace{-1.5em}
+% \TeX{} Live realeases: \\
+% \calcage{2012}{07}{08} \\
+% \calcage{2011}{07}{20} \\
+% \calcage{2010}{09}{10} \\
+% \calcage{2009}{11}{09}
+%
+% \begin{verbatim}
+% Donald Knuth is \calcage{1938}{01}{10} old. \\
+% Donald Knuth will be 100 years old in
+% \calcage[positive, precision]{2038}{01}{10}. \\
+% Albert Einstein died at the age of
+% \calcage[year=1955, month=04, day=18]{1879}{03}{14}. \\
+% Age of Linus Torvalds in years: \calcage[printyear=false]{1969}{12}{28} \\
+% \end{verbatim}\vspace{-1.5em}
+% Donald Knuth is \calcage{1938}{01}{10} old. \\
+% Donald Knuth will be 100 years old in
+% \calcage[positive, precision]{2038}{01}{10}. \\
+% Albert Einstein died at the age of
+% \calcage[year=1955, month=04, day=18]{1879}{03}{14}. \\
+% Age of Linus Torvalds in years: \calcage[printyear=false]{1969}{12}{28} \\
+%
+% \StopEventually{}
+%
+% \newpage
+% \section{Implementation}
+% \iffalse
+%<*package>
+% \fi
+% This package depends on these packages.
+% \begin{macrocode}
+\RequirePackage{fnumprint}[2012/08/27]
+\RequirePackage{
+ datenumber,
+ fp,
+ calc,
+ xkeyval,
+ kvoptions,
+ xifthen,
+}
+% \end{macrocode}
+% \subsection{Declaring the options}
+% \begin{macrocode}
+\DeclareStringOption{year}
+\DeclareStringOption{month}
+\DeclareStringOption{day}
+\DeclareStringOption{precision}[3]
+\DeclareBoolOption{positive}
+\DeclareBoolOption{printyear}
+\DeclareBoolOption{yearsuffix}
+\DeclareBoolOption{numberstring}
+% \end{macrocode}
+% To test if all parameters are valid the macro |\ProcessLocalKeyvalOptions*|
+% is expanded to ensure this before leaving the preamble. This is the only
+% purpose for the |\ProcessLocalKeyvalOptions*| macro in this case.
+% \begin{macrocode}
+\ProcessLocalKeyvalOptions*
+% \end{macrocode}
+% The next source code line creates a new macro which captures the parameters
+% to use them as default options for the macro |\calcage|.
+% If this macro is set to \enquote{precision=4} for example the |\setkeys| is
+% going to fail.
+% \begin{macrocode}
+\edef\calcage@options{\@ptionlist{\@currname.\@currext}}
+%% ^^A \renewcommand{\calcage@options}{precision=4,printyear=false}
+%% ^^A Package xkeyval Error: `precision=4' undefined in families `calcage'.
+% \end{macrocode}
+% \subsection{Language selection}
+% Here comes the language selection part. The counter is already set by the
+% \PrintPackage{fnumprint} so I use it's value also in this package because I
+% can rely on this counter.\footnote{I am also the maintainer of the
+% \PrintPackage{fnumprint} package~\dots}
+% If you prefer another language than English or German you can redefine the
+% following macro definitions.
+% \begin{macrocode}
+\ifcase\value{fnumprint@language}\or
+% \end{macrocode}
+% If fnumprint@language is equal 1
+% \begin{macrocode}
+ \newcommand{\calcage@yearWord}{Jahr}
+ \newcommand{\calcage@yearPluralSuffix}{e}
+ \newcommand{\calcage@yearSuffix}{n}
+\or
+% \end{macrocode}
+% If fnumprint@language is equal 2
+% \begin{macrocode}
+ \newcommand{\calcage@yearWord}{year}
+ \newcommand{\calcage@yearPluralSuffix}{s}
+ \newcommand{\calcage@yearSuffix}{}
+\fi
+% \end{macrocode}
+% \subsection{Macro definition}
+% Some necessary \LaTeX{} counters are declared here before creating the
+% |\calcage| macro.
+% \begin{macrocode}
+\newcounter{calcage@today}\newcounter{calcage@ageindays}
+\newcounter{calcage@myyear}\newcounter{calcage@leapyears}
+% \end{macrocode}
+% \begin{macro}{\calcage}
+% And now comes the important part -- the definition of |\calcage|.
+% The first thing that has to be done is expanding the |\setkeys| macro. It
+% sets the default options then the package options get the opportunity to
+% overwrite these settings and finally the macro options get the same
+% possibility.
+% \begin{macrocode}
+\newcommand{\calcage}[4][]{%
+ \setkeys{calcage}{precision=0, positive=true, printyear=true,
+ yearsuffix=false, numberstring=true,
+ year=\the\year, month=\the\month, day=\the\day, \calcage@options, #1}%
+ \setmydatenumber{calcage@today}{\calcage@year}{\calcage@month}{\calcage@day}%
+ \setmydatenumber{calcage@ageindays}{#2}{#3}{#4}%
+% \end{macrocode}
+% Now comes the tricky part which are the leap years~\dots \\
+% My first implementation worked with dividing by $365.2425$ but this was not
+% perfect. So the current implementation counts how many leap years are between
+% the birth year and the current year and subtracts (or adds\footnote{If the
+% birth year is in the future because in this case the calcage@ageindays
+% counter will be negative.}) this number.
+% \begin{macrocode}
+ \setcounter{calcage@myyear}{#2}%
+ \setcounter{calcage@leapyears}{0}%
+ \ifthenelse{\equal{#2}{\calcage@year}}{}{%
+ \ifthenelse{\value{calcage@myyear}<\calcage@year}{%
+% \end{macrocode}
+% If the birth year is in the past.
+% \begin{macrocode}
+ \loop%
+ \stepcounter{calcage@myyear}%
+ \ifleapyear{\thecalcage@myyear}\stepcounter{calcage@leapyears}\fi%
+ \ifnum\value{calcage@myyear}<\calcage@year%
+ \repeat%
+ }{%
+% \end{macrocode}
+% If the birth year is in the future.
+% \begin{macrocode}
+ \loop%
+ \ifleapyear{\thecalcage@myyear}\addtocounter{calcage@leapyears}{-1}\fi%
+ \addtocounter{calcage@myyear}{-1}%
+ \ifnum\value{calcage@myyear}>\calcage@year%
+ \repeat%
+ }%
+ }%
+ \setcounter{calcage@ageindays}{\value{calcage@today}
+ - \value{calcage@ageindays} - \value{calcage@leapyears}}%
+ \ifthenelse{\boolean{calcage@positive} \AND \value{calcage@ageindays} < 0}{%
+ \setcounter{calcage@ageindays}{\value{calcage@ageindays} * -1}%
+ }{}%
+% \end{macrocode}
+% Because we know that every year has now exactly 365 days we can divide by
+% that.
+% \begin{macrocode}
+ \FPdiv\calcage@age{\thecalcage@ageindays}{365}%
+% \end{macrocode}
+% The next step is to truncated the age. There is no rounding used for this. I
+% implemented it this way because if the age would be rounded then there would
+% be a wrong result in cases like $x.999$ which would become $x+1$ if
+% \enquote{precision=0} and that is probably not what you want~\dots
+% \begin{macrocode}
+ \FPtrunc\calcage@age{\calcage@age}{\calcage@precision}%
+% \end{macrocode}
+% The last thing to do is to typeset the age which is implemented by the next
+% few lines of code.
+% \begin{macrocode}
+ \ifthenelse{\boolean{calcage@numberstring}
+ \AND \equal{\calcage@precision}{0}}%
+ {\fnumprint[ein]{\calcage@age}}{\numprint{\calcage@age}}%
+ \ifthenelse{\boolean{calcage@printyear}}{%
+ ~\calcage@yearWord%
+ \ifthenelse{\equal{\calcage@age}{1} \OR \equal{\calcage@age}{-1}}{}{%
+ \calcage@yearPluralSuffix%
+ \ifthenelse{\boolean{calcage@yearsuffix}}{\calcage@yearSuffix}{}%
+ }%
+ }{}%
+}
+% \end{macrocode}
+% \end{macro}
+% That's it.
+% \begin{macrocode}
+\endinput
+% \end{macrocode}
+%
+% \iffalse
+%</package>
+% \fi
+%
+% \Finale
+\endinput
diff --git a/Master/texmf-dist/source/latex/calcage/calcage.ins b/Master/texmf-dist/source/latex/calcage/calcage.ins
new file mode 100644
index 00000000000..6f380d82208
--- /dev/null
+++ b/Master/texmf-dist/source/latex/calcage/calcage.ins
@@ -0,0 +1,23 @@
+%% See file 'calcage.dtx' for copyright and licence.
+\input docstrip.tex
+
+\keepsilent
+\usedir{tex/latex/calcage}
+\usepreamble\mypreamble
+\askforoverwritefalse
+\generate{\nopreamble\file{calcage.sty}{\from{calcage.dtx}{package}}}
+
+\Msg{***********************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* file into a directory searched by TeX:}
+\Msg{*}
+\Msg{* \space\space calcage.sty}
+\Msg{*}
+\Msg{* To produce the documentation run the files}
+\Msg{* `calcage.dtx' through LaTeX.}
+\Msg{*}
+\Msg{* Happy TeXing}
+\Msg{***********************************************************}
+
+\endbatchfile
diff --git a/Master/texmf-dist/tex/latex/calcage/calcage.sty b/Master/texmf-dist/tex/latex/calcage/calcage.sty
new file mode 100644
index 00000000000..61c7fc4ea74
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/calcage/calcage.sty
@@ -0,0 +1,80 @@
+%% See file 'calcage.dtx' for copyright and licence.
+\NeedsTeXFormat{LaTeX2e}[1998/12/01]
+\ProvidesPackage{calcage}
+ [2012/09/09 v0.90 Calculate the age in years]
+\RequirePackage{fnumprint}[2012/08/27]
+\RequirePackage{
+ datenumber,
+ fp,
+ calc,
+ xkeyval,
+ kvoptions,
+ xifthen,
+}
+\DeclareStringOption{year}
+\DeclareStringOption{month}
+\DeclareStringOption{day}
+\DeclareStringOption{precision}[3]
+\DeclareBoolOption{positive}
+\DeclareBoolOption{printyear}
+\DeclareBoolOption{yearsuffix}
+\DeclareBoolOption{numberstring}
+\ProcessLocalKeyvalOptions*
+\edef\calcage@options{\@ptionlist{\@currname.\@currext}}
+%% ^^A \renewcommand{\calcage@options}{precision=4,printyear=false}
+%% ^^A Package xkeyval Error: `precision=4' undefined in families `calcage'.
+\ifcase\value{fnumprint@language}\or
+ \newcommand{\calcage@yearWord}{Jahr}
+ \newcommand{\calcage@yearPluralSuffix}{e}
+ \newcommand{\calcage@yearSuffix}{n}
+\or
+ \newcommand{\calcage@yearWord}{year}
+ \newcommand{\calcage@yearPluralSuffix}{s}
+ \newcommand{\calcage@yearSuffix}{}
+\fi
+\newcounter{calcage@today}\newcounter{calcage@ageindays}
+\newcounter{calcage@myyear}\newcounter{calcage@leapyears}
+\newcommand{\calcage}[4][]{%
+ \setkeys{calcage}{precision=0, positive=true, printyear=true,
+ yearsuffix=false, numberstring=true,
+ year=\the\year, month=\the\month, day=\the\day, \calcage@options, #1}%
+ \setmydatenumber{calcage@today}{\calcage@year}{\calcage@month}{\calcage@day}%
+ \setmydatenumber{calcage@ageindays}{#2}{#3}{#4}%
+ \setcounter{calcage@myyear}{#2}%
+ \setcounter{calcage@leapyears}{0}%
+ \ifthenelse{\equal{#2}{\calcage@year}}{}{%
+ \ifthenelse{\value{calcage@myyear}<\calcage@year}{%
+ \loop%
+ \stepcounter{calcage@myyear}%
+ \ifleapyear{\thecalcage@myyear}\stepcounter{calcage@leapyears}\fi%
+ \ifnum\value{calcage@myyear}<\calcage@year%
+ \repeat%
+ }{%
+ \loop%
+ \ifleapyear{\thecalcage@myyear}\addtocounter{calcage@leapyears}{-1}\fi%
+ \addtocounter{calcage@myyear}{-1}%
+ \ifnum\value{calcage@myyear}>\calcage@year%
+ \repeat%
+ }%
+ }%
+ \setcounter{calcage@ageindays}{\value{calcage@today}
+ - \value{calcage@ageindays} - \value{calcage@leapyears}}%
+ \ifthenelse{\boolean{calcage@positive} \AND \value{calcage@ageindays} < 0}{%
+ \setcounter{calcage@ageindays}{\value{calcage@ageindays} * -1}%
+ }{}%
+ \FPdiv\calcage@age{\thecalcage@ageindays}{365}%
+ \FPtrunc\calcage@age{\calcage@age}{\calcage@precision}%
+ \ifthenelse{\boolean{calcage@numberstring}
+ \AND \equal{\calcage@precision}{0}}%
+ {\fnumprint[ein]{\calcage@age}}{\numprint{\calcage@age}}%
+ \ifthenelse{\boolean{calcage@printyear}}{%
+ ~\calcage@yearWord%
+ \ifthenelse{\equal{\calcage@age}{1} \OR \equal{\calcage@age}{-1}}{}{%
+ \calcage@yearPluralSuffix%
+ \ifthenelse{\boolean{calcage@yearsuffix}}{\calcage@yearSuffix}{}%
+ }%
+ }{}%
+}
+\endinput
+%%
+%% End of file `calcage.sty'.
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index 3fb891cb122..d0b45f309bf 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -76,7 +76,7 @@ my @TLP_working = qw(
boxedminipage boxhandler bpchem bpolynomial
bracketkey braids braille braket breakcites breakurl
bullcntr bundledoc burmese bussproofs bytefield
- c-pascal cachepic calctab calculator
+ c-pascal cachepic calcage calctab calculator
calligra calligra-type1 calrsfs cals calxxxx-yyyy cancel
canoniclayout cantarell
capt-of captcont captdef caption carlisle carolmin-ps
diff --git a/Master/tlpkg/tlpsrc/calcage.tlpsrc b/Master/tlpkg/tlpsrc/calcage.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/calcage.tlpsrc
diff --git a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
index a1eacecebab..63124e9906a 100644
--- a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
@@ -74,6 +74,7 @@ depend braket
depend breakurl
depend bullcntr
depend bussproofs
+depend calcage
depend calctab
depend calculator
depend calrsfs