The isodateo package^{∗}

Harald Harders

               h.harders@tu-bs.de

File Date 2000-08-08, Printed 2001-05-17

Abstract

This package provides commands to switch between different date formats (standard, ISO, numeric, L^{A}TEX package). They are used by the \today command and by the \printdate and \printdateTeX commands that print any date. This package supports German (old and new rules, Austrian), US English, and all languages that have the same date format as British English does^{1}.

The idea for this package was taken from the akletter class.

Contents

1 Commands 1 1.1 Switching the date format . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 Printing any date . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.3 Changing the ISO format . . . . . . . . . . . . . . . . . . . . . . . 2

2 Calling the package 3

A Licence 3

B Known errors 3

C Planned features and changes 3

D The implementation 3

1 Commands

1.1 Switching the date format

\today This package provides five commands to switch the output format of the \today,

the \printdate, and the \printdateTeX commands:

∗This file has version 1.06 last revised 2000-08-08, documentation dated 2000-08-08.

1E.g. Danish, French

\isodate  date format described in ISO 8601 and DIN 5008

(yyyy-mm-dd)

\numdate  numeric date format with four digits of the year
\shortdate short numeric date format with two digits of the year
\TeXdate  date format used for version description of packages

(yyyy/mm/dd)

\origdate original L^{A}TEX format

\isodate
\numdate
\shortdate
\TeXdate
\origdate

The numeric and short numeric format change their behaviour depending on the actual language:

German, nGerman dd.\,mm.~yyyy resp. dd.\,mm.\,yy
US English  mm/dd/yyyy  resp. mm/dd/yy

other languages  dd/mm/yyyy  resp. dd/mm/yy

So this package supports German (old and new rules, Austrian), US English, and all languages that have the same date format as British English does^{2}. Switching the language by using \selectlanguage also switches back to the original date format.

1.2 Printing any date

\printdate The command \printdate{#1} prints any date in the actual format. The argument may be a date in German, British English, or ISO format, e.g.

     \printdate{24.12.2000}
     \printdate{24/12/2000}
     \printdate{2000-12-24}

\printdateTeX The command \printdateTeX{#1} prints any date in the actual format. The argument must be in the L^{A}TEX format yyyy/mm/dd, e.g.

     \printdateTeX{2000/12/24}

This command is useful for printing version information stored in a macro. For example the version of this documentation is stored in the macro \docdate (“2000/08/08”). To print it with the actual date format you can use the command \printdateTeX{\docdate} which leads to “2000-08-08”.

1.3 Changing the ISO format

\isodash I am not sure whether the ISO format should be yyyy-mm-dd or yyyy–mm–dd. By default I use “-” as dash. You can change this using the \isodash command, e.g.

     \printdate{24/12/2000}
     \isodash{--}
     \printdate{24/12/2000}

leads to “2000-12-24 2000–12–24”. Or for example

     \isodash{$\cdot$}
     \printdate{24/12/2000}

leads to “2000·12·24”.

2E.g. Danish, French

2 Calling the package

The package is called using the \usepackage command:

\usepackage[option]{isodate}.

The possible package options can be seen in table 1.

Table 1: Package options

option used date format
iso  ISO date format
num  numeric date format with 4 digits of the year
short numeric date format with 2 digits of the year
TeX  L^{A}TEX numeric date format (yyyy/mm/dd)
orig normal L^{A}TEX date format (default)

A Licence

Copyright 2000 Harald Harders

This program can be redistributed and/or modified under the terms of the LaTeX Project Public License Distributed from CTAN archives in directory macros/latex/base/lppl.txt; either version 1 of the License, or any later version.

B Known errors

• The \printdate and \printdateTeX commands are not very good in checking the argument for correct syntax.

• For the language American: Using the package babel only the language name “american” works, using the package *german only “USenglish” works.

C Planned features and changes

• Of course eliminate the errors.

• Add other languages then german, ngerman, english, USenglish. Please help me with this topic, I don’t know the date formats in other languages.

D The implementation

Heading of the package:

 1 \NeedsTeXFormat{LaTeX2e}
 2 \ProvidesPackage{isodateo}[\filedate]
 3 \RequirePackage{ifthen}
 4 \RequirePackage{calc}
 5 \IfFileExists{substr.sty}{\RequirePackage{substr}%
 6 }{\PackageError{isodateo.sty}{Package file substr.sty not found}
 7 {This version of isodateo.sty needs the package substr.sty.^^J%
 8  You can download it from CTAN:/macros/latex/contrib/supported/substr/^^J%

 9  E.g. one CTAN node is ftp.dante.de.
10  Install substr.sty into your TeX tree.}}

At the end of the preamble the package tests whether one of the packages babel, german, or ngerman is loaded. If not it is assumed that American English is wanted (L^{A}TEX is an American programme). The original date format is saved and the command \iflanguage is redefined to process the “true part” for english, american, and USenglish options and otherwise the “false part”.

11 \AtBeginDocument{%
12 \@ifpackageloaded{babel}{}{%
13  \@ifpackageloaded{german}{}{%
14  \@ifpackageloaded{ngerman}{}{%

Here you can add new languages. Tell me what you have inserted in order to enable me to actualize the package.

15  \let\dateamerican\today%
16  \setboolean{isodate@american}{true}%
17  \def\iflanguage#1#2#3{\ifthenelse{%
18  \equal{#1}{english}\or%
19  \equal{#1}{american}\or%
20  \equal{#1}{USenglish}%
21  }{#2}{#3}}%
22  }}}}

Declare the boolean variable isodate@american. This is necessary because the command \iflanguage cannot decide if the language is English or American.

23 \newboolean{isodate@american}%
24 % \changes{1.06}{2000/08/08}{Avoid using the hack with redefining
25 % \selectlanguage}
26 % Define the package options.
27 %    \begin{macrocode}
28 \DeclareOption{iso}{\AtBeginDocument{\isodate}}
29 \DeclareOption{num}{\AtBeginDocument{\numdate}}
30 \DeclareOption{short}{\AtBeginDocument{\shortdate}}
31 \DeclareOption{TeX}{\AtBeginDocument{\TeXdate}}
32 \DeclareOption{orig}{\AtBeginDocument{\origdate}}
33 \ExecuteOptions{orig}
34 \ProcessOptions

Print day or month filled with zero to a format with two digits.

35 \def\dday{\ifthenelse{\number\day<10}{0}{}\number\day}
36 \def\dmonth{\ifthenelse{\number\month<10}{0}{}\number\month}

Print day and month in numerical format using the right format for the present language.

37 \DeclareRobustCommand*{\num@today}[1]{%
38 \iflanguage{german}{\dday.\,\dmonth.#1}{%
39  \iflanguage{austrian}{\dday.\,\dmonth.#1}{%
40  \iflanguage{ngerman}{\dday.\,\dmonth.#1}{%
41  \iflanguage{naustrian}{\dday.\,\dmonth.#1}{%

Here you can add new languages. Tell me what you have inserted in order to enable me to actualize the package.

42  \iflanguage{english}{%
43  \ifthenelse{\boolean{isodate@american}}{%
44  \dmonth/\dday/}{\dday/\dmonth/}}{%

45 \dday/\dmonth/}}}}}%

46 }

\numdate Switch to long numeric date format.

47 \DeclareRobustCommand*{\numdate}{%

Find out whether the language may be English or American. The English original date format does not contain a komma while the american does.

48 \origdate%
49 \setboolean{isodate@american}{false}%
50 \iflanguage{american}{\IfCharInString{,}{\today}{%
51  \setboolean{isodate@american}{true}}{}}{}%

Define the new \today command.

52 \gdef\today{%
53  \num@today{~}%
54  \number\year}}

\shortdate Switch to short numeric date format.

55 \newcounter{yeartwo}
56 \DeclareRobustCommand*{\shortdate}{%

Find out whether the language may be English or American. The English original date format does not contain a komma while the american does.

57 \origdate%
58 \setboolean{isodate@american}{false}%
59 \iflanguage{american}{\IfCharInString{,}{\today}{%
60  \setboolean{isodate@american}{true}}{}}{}%

Define the new \today command.

61 \gdef\today{%
62  \num@today{\,}%
63  \setcounter{yeartwo}{\number\year}%
64  \whiledo{\theyeartwo>99}{\setcounter{yeartwo}{\theyeartwo-100}}{}%
65  \ifthenelse{\number\theyeartwo<10}{0}{}\theyeartwo}}

\isodate Switch to ISO date format.

66 \DeclareRobustCommand*{\isodate}{%
67 \gdef\today{%
68  \number\year\iso@isodash%
69  \ifthenelse{\number\month<10}{0}{}\number\month\iso@isodash%
70  \ifthenelse{\number\day<10}{0}{}\number\day}}

Define the default ISO dash to “-”.

71 \def\iso@isodash{-}%

\isodate Define the command \isodash which changes the dash in the ISO date format.

72 \DeclareRobustCommand*{\isodash}[1]{\def\iso@isodash{#1}}%

\origdate Switch back to original date format.

73 %\DeclareRobustCommand*{\origdate}{\gdef\today{\iso@origdate}}
74 \DeclareRobustCommand*{\origdate}{\csname date\languagename\endcsname}

\TeXdate Switch to the TEX date format.

75 \DeclareRobustCommand*{\TeXdate}{%
76 \gdef\today{%
77  \number\year/%
78  \ifthenelse{\number\month<10}{0}{}\number\month/%
79  \ifthenelse{\number\day<10}{0}{}\number\day}}

Print any date (internal command, syntax: \iso@printdate{yyyy}{mm}{dd}).

80 \DeclareRobustCommand*{\iso@printdate}[3]{%
81 \begingroup%
82 \def\year{#1}%
83 \def\month{#2}%
84 \def\day{#3}%
85 \today%
86 \endgroup%

87 }

Define counters to count the numbers of special characters in the arguments of

the \printdate and \printdateTeX commands.
88 \newcounter{iso@slash}
89 \newcounter{iso@minus}
90 \newcounter{iso@dot}

\printdate Print any date in the actual date format. This command understands the German, British, and ISO formats.

91 \DeclareRobustCommand*{\printdate}[1]{%
92 \expandafter\iso@expafterprintdate\expandafter{#1}}%
\iso@expafterprintdate The command \iso@expafterprintdate needs an already expanded argument.
So the command \printdate expands it and calls \iso@expafterprintdate.

The error handling of this macro is very poor. It is just tested if either a “/”, “-”, or “.” is included in the argument twice. It is not tested if the argument consists of numbers, only.

93 \DeclareRobustCommand*{\iso@expafterprintdate}[1]{%
94 \SubStringsToCounter{iso@slash}{/}{#1}%
95 \SubStringsToCounter{iso@minus}{-}{#1}%
96 \SubStringsToCounter{iso@dot}{.}{#1}%
97 \ifthenelse{\equal{\theiso@dot}{2}}{\printdatenumger{#1}}{%
98  \ifthenelse{\equal{\theiso@minus}{2}}{\printdateiso{#1}}{%
99  \ifthenelse{\equal{\theiso@slash}{2}}{\printdatenumeng{#1}}{%
100  ????\iso@isodash ??\iso@isodash ??%
101  \PackageError{isodateo}{unrecognized date format}{Use one of
102  the following formats as macro argument:^^J%
103  \space\space dd.mm.yyyy^^J%
104  \space\space dd/mm/yyyy^^J%
105  \space\space yyyy-mm-dd^^J%
106  Don't use any spaces or commands like \protect\, or
107  \protect~ inside the argument.}%
108  }}}}

Analyze the argument containing a date in ISO format an print it. This macros does not contain any error handling.

109 \DeclareRobustCommand*{\printdateiso}[1]{%

110 \expandafter\iso@printdateiso #1\@empty}
111 \def\iso@printdateiso#1-#2-#3\@empty{\iso@printdate{#1}{#2}{#3}}

Analyze the argument containing a date in German numeric format an print it. This macros does not contain any error handling.

112 \DeclareRobustCommand*{\printdatenumger}[1]{%
113 \expandafter\iso@printdatenumger #1\@empty}
114 \def\iso@printdatenumger#1.#2.#3\@empty{\iso@printdate{#3}{#2}{#1}}

Analyze the argument containing a date in Britisch English numeric format an print it. This macros does not contain any error handling.

115 \DeclareRobustCommand*{\printdatenumeng}[1]{%
116 \expandafter\iso@printdatenumeng #1\@empty}
117 \def\iso@printdatenumeng#1/#2/#3\@empty{\iso@printdate{#3}{#2}{#1}}

\printdateTeX Analyze the argument containing a date in the LaTeX style yyyy/mm/dd an print it. This format can not be handled automaticaly by \printdate because it could be mixed up with the English format. The error handling of this routine is very poor. It just checks whether the argument contains at least one “/”.

118 \DeclareRobustCommand*{\printdateTeX}[1]{%
119 \expandafter\iso@printdateTeX\expandafter{#1}}
120 \DeclareRobustCommand*{\iso@printdateTeX}[1]{%
121 \SubStringsToCounter{iso@slash}{/}{#1}%
122 \ifthenelse{\equal{\theiso@slash}{2}}%
123 {\expandafter\iso@@printdateTeX #1\@empty}{%
124  ????\iso@isodash ??\iso@isodash ??%
125  \PackageError{isodateo}{unrecognized date format}{Use the format
126  yyyy/mm/dd.^^J%
127  Don't use any spaces or commands like \protect\, or
128  \protect~ inside the argument.}}%

129 }

130 \def\iso@@printdateTeX#1/#2/#3\@empty{\iso@printdate{#1}{#2}{#3}}

The end of the package.

Change History

1.01

General: Improve documentation . 1 1.02

General: Fix American language

support by a hack . . . . . . . . . . 4 1.03

General: Insert code for handling

not loaded language packages . 4 1.04

General: Add L^{A}TEX date format yyyy/mm/dd . . . . . . . . . . . . . 7 Make the commands robust … 1

\TeXdate: Add L^{A}TEX date format yyyy/mm/dd . . . . . . . . . . . . . 6 1.05

General: Change all internal command names to start with \iso@ . . . . . . . . . . . . . . . . . . . 1 Note that every language that has the same format as English is supported. . . . . . . . . . . . . . . 2 Throw out the commands \IfSubStringInString and \IfCharInString and use the package substr.sty instead …. 1

                                           \iso@expafterprintdate: Count

appearances of “/”, “.”, and “- ” and complain if not at least one of them is equal to 2 . . . . . 6 \printdateTeX: Count appearances

of “/” and complain if not equal to 2 . . . . . . . . . . . . . . . . . . . . 7

1.06

\numdate: Choose between English and American language . . . . . . 5 \origdate: Use the command

\datelanguage to switch back to the original date format … 5

\shortdate: Choose between English and American language . . 5

Index

Numbers written in italic refer to the page where the corresponding entry is described, the ones underlined to the code line of the definition, the rest to the code lines where the entry is used.

Symbols

\@ifpackageloaded .

. . . . . . . . . 12–14

A

\AtBeginDocument . .

. . . . . . . 11, 28–32

B

\begin . . . . . . . . . . . 27

\begingroup . . . . . . . 81

\boolean . . . . . . . . . 43

C

\changes . . . . . . . . . 24 \csname . . . . . . . . . . 74

D

\dateamerican . . . . . 15

\day . . . . . 35, 70, 79, 84 \dday . . 35, 38–41, 44, 45

\DeclareOption . . 28–32
\DeclareRobustCommand

. . . . . . 37, 47, 56, 66, 72–75, 80, 91, 93, 109, 112, 115, 118, 120

\dmonth 36, 38–41, 44, 45

E

\endcsname . . . . . . . 74

\endgroup . . . . . . . . 86 \equal 18–20, 97–99, 122

\ExecuteOptions . . . 33
\expandafter 92, 110,

113, 116, 119, 123

F

\filedate . . . . . . . . . 2

I

\IfCharInString . 50, 59
\IfFileExists . . . . . . 5
\iflanguage . . . . . . .

. 17, 38–42, 50, 59

\ifthenelse 17, 35, 36,

43, 65, 69, 70, 78, 79, 97–99, 122

\iso@@printdateTeX .

. . . . . . . . 123, 130

\iso@expafterprintdate

. . . . . . . . . 92, \underline{93}

\iso@isodash . . . 68,

69, 71, 72, 100, 124

\iso@origdate . . . . . 73
\iso@printdate . 80,

111, 114, 117, 130

\iso@printdateiso .

. . . . . . . . 110, 111

\iso@printdatenumeng

. . . . . . . . 116, 117

\iso@printdatenumger

. . . . . . . . 113, 114

\iso@printdateTeX .

. . . . . . . . 119, 120 \isodash . . . . . . . . 2, 72 \isodate . . 2, 28, \underline{66}, \underline{72}

L

\languagename . . . . . 74

M

\month … 36, 69, 78, 83

N

\NeedsTeXFormat . . . . 1
\newboolean . . . . . . . 23
\num@today . . 37, 53, 62

\numdate . . . . . 2, 29, \underline{47}

O

\or . . . . . . . . . . . 18, 19 \origdate 2, 32, 48, 57, \underline{73}

P

\PackageError 6, 101, 125
\printdate . . . . . . 2, \underline{91}
\printdateiso . . 98, 109
\printdatenumeng 99, 115
\printdatenumger 97, 112
\printdateTeX . . . 2, \underline{118}
\ProcessOptions . . . 34

\protect . . . . . . . . .

. 106, 107, 127, 128

\ProvidesPackage . . . 2

R

\RequirePackage . . . 3–5

S

\selectlanguage . . . 25
\shortdate . . . 2, 30, \underline{55}
\SubStringsToCounter

. . . . . . 94–96, 121

T

\TeXdate . . . . . 2, 31, \underline{75}

\theiso@dot . . . . . . . 97
\theiso@minus . . . . . 98
\theiso@slash . . 99, 122
\theyeartwo . . . . . 64, 65

\today 1, 15, 50, 52, 59, 61, 67, 73, 76, 85

Y

\year . . 54, 63, 68, 77, 82