summaryrefslogtreecommitdiff
path: root/macros/latex209/contrib/misc/dates.sty
blob: 607d45d0aec5a745db2660ab07ae9a7986b7da28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
% --- ------------------------------------------------------------------
% ---                            dates.sty
% ---          Flexible Date Macros for LaTeX, version 1.00--1
% --- ------------------------------------------------------------------
% ---         Adrian F. Clark  (alien@uk.ac.essex)   4-Aug-1992
% --- ------------------------------------------------------------------
%
% --- \today            generates today's date.  Alter this to suit
% ---                   the way you want it to appear.  It is currently
% ---                   set up to generate dates in the form
% ---                          `Thursday 4th October 1066'
%
% --- \thisdayofweek    generates today's day name (`Sunday', etc).
% --- \thisday          generates today's day (`1', `2', etc).
% --- \thisdayth        generates today's day (`1st', `2nd', etc),
% ---                   where the `st' etc are generated by \st etc.
% --- \thismonth        generates today's month (`January', etc).
% --- \thisyear         generates today's year.
% --- \thisphaseofmoon  generates the current phase of the moon.
%
% --- \dayofweek{year}{month}{day}  generates the day of the week for
%            the given date.
%
% --- \phaseofmoon{year}{month}{day}  generates the phase of the moon
%            for the given date.
%
% --- \Sunday (etc)   generates `Sunday' (etc).
% --- \January (etc)  generates 'January' (etc).
% --- \NewMoon (etc)  generates `new' (etc).
%
% --- \st    generates a raised, reduced, underlined `st', as in 1st.
% --- \nd    generates a raised, reduced, underlined `nd', as in 2nd.
% --- \rd    generates a raised, reduced, underlined `rd', as in 3rd.
% --- \th    generates a raised, reduced, underlined `th', as in 4th.

% --- ------------------------------------------------------------------
% --- The actual date macros.

% --- As distributed, \today generates today's date in the style
% --- `Thursday 4th October 1066'.  

\def\today{\thisdayofweek\ \thisdayth\ \thismonth\ \thisyear}

\def\thisday{\number\day}

\def\thisdayth{\thisday \ifcase\day
  \or\st\or\nd\or\rd\or\th\or\th\or\th\or\th\or\th\or\th\or\th
  \or\th\or\th\or\th\or\th\or\th\or\th\or\th\or\th\or\th\or\th
  \or\st\or\nd\or\rd\or\th\or\th\or\th\or\th\or\th\or\th\or\th\or\st\fi}

\def\thisdayofweek{\dayofweek{\year}{\month}{\day}}

\def\thismonth{\ifcase\month\or \January\or \February\or \March\or
  \April\or \May\or \June\or \July\or \August\or \September\or
  \October\or \November\or \December\fi}

\def\thisyear{\number\year}

\def\thisphaseofmoon{\phaseofmoon{\year}{\month}{\day}}

% --- ------------------------------------------------------------------
% --- Names of days of the week, the months, and the phases of the moon.
% --- This makes it easier to change them for languages other than English.
% --- (And that's why they're not \@Sunday, etc).

\def\Sunday{Sunday}
\def\Monday{Monday}
\def\Tuesday{Tuesday}
\def\Wednesday{Wednesday}
\def\Thursday{Thursday}
\def\Friday{Friday}
\def\Saturday{Saturday}

\def\January{January}
\def\February{February}
\def\March{March}
\def\April{April}
\def\May{May}
\def\June{June}
\def\July{July}
\def\August{August}
\def\September{September}
\def\October{October}
\def\November{November}
\def\December{December}

\def\NewMoon{new}
\def\WaxCresMoon{waxing crescent}
\def\FirstQuarterMoon{in its first quarter}
\def\WaxGibMoon{waxing gibbous}
\def\FullMoon{full}
\def\WaneGibMoon{waning gibbous}
\def\LastQuarterMoon{in its last quarter}
\def\WaneCresMoon{waning crescent}


% --- ------------------------------------------------------------------
% --- Counters.  Note that we use the same registers as TeX holds other
% --- things in (e.g., \count0 holds the page number).  This requires
% --- that \@savestyle, \@setstyle, \dayofweek and \phaseofmoon perform
% --- all their register manipulations within a group.  This may seem
% --- a bit messy, but it saves having eight registers permanently set
% --- aside just for date calculation.

\def\@cent{\count0 }                       % century number (1979 == 20)
\def\@diy{\count1 }                        % day in the year
\def\@dow{\count2 }                        % gets day of the week
\def\@epact{\count3 }                      % age of the moon on Jan. 1
\def\@golden{\count4 }                     % Moon's golden number
\def\@leap{\count5 }                       % leap year fingaler
\def\@x{\count6 }                          % temp register
\def\@y{\count7 }                          % another temp register

% --- ------------------------------------------------------------------
% --- For `old' (pre version 2.10) LaTeX, these macros ensure the
% --- smaller text comes out in the right font by saving the font
% --- family before reducing the size, then restoring it.
% --- (This hack was suggested by Leslie Lamport.)  Of course, it
% --- requires that the font in use when the caller is invoked has
% --- a sensible family.

% --- For LaTeX 2.10 onwards, which uses the font selection scheme due
% --- to Mittelbach and Shoepf, such a hack is not necessary.  The
% --- macros detect which version is in use automagically.

\def\st{\alien@up{st}}
\def\nd{\alien@up{nd}}
\def\rd{\alien@up{rd}}
\def\th{\alien@up{th}}

\def\alien@up#1{{\@savestyle\thinspace$^{\underline{\hbox{%
  \scriptsize\@setstyle#1\fam=-1 }}}$}}

% --- Macros to save and restore the font family.

\def\@savestyle{\count0=\the\fam}

\def\@setstyle{\ifcase\count0\rm\or\mit\or\cal\or\rm% what's family 3?
  \or\it\or\sl\or\bf\or\tt\fi}

% --- ------------------------------------------------------------------
% --- The nitty-gritty.

% --- The day of the week (\Sunday, etc.) is inserted into the text
% --- by \dayofweek. (This uses registers \@dow, \@leap, \@x and \@y.)
% --- I acquired this from elsewhere; it was apparently written by
% --- Martin Minow, now a DEC employee.  The algorithms is:
% ---   leap = year + (month - 14)/12;
% ---   dow = (13 * (month + 10 - (month + 10)/13*12) - 1)/5
% ---   dow += day + 77 + 5 * (leap % 100)/4
% ---   dow += leap / 400
% ---   dow -= leap / 100 * 2
% ---   dow = (dow % 7)

\def\dayofweek#1#2#3{{\@leap=#2\advance\@leap by -14\divide\@leap by 12\relax
  \advance\@leap by #1\relax
  \@dow=#2\advance\@dow by 10\relax
  \@y=\@dow \divide\@y by 13\multiply\@y by 12\relax
  \advance\@dow by -\@y \multiply\@dow by 13\relax
     \advance\@dow by -1 \divide\@dow by 5\relax
  \advance\@dow by #3\advance\@dow by 77\relax
  \@x=\@leap \@y=\@x \divide\@y by 100\multiply\@y by 100\relax
     \advance\@x by -\@y \relax
  \multiply\@x by 5\divide\@x by 4\advance\@dow by \@x
  \@x=\@leap \divide\@x by 400\advance\@dow by \@x
  \@x=\@leap \divide\@x by 100\multiply\@x by 2\advance\@dow by -\@x
  \@x=\@dow \divide\@x by 7\multiply\@x by 7\advance\@dow by -\@x
  \ifcase\@dow \Sunday\or \Monday\or \Tuesday\or \Wednesday\or
      \Thursday\or \Friday\or \Saturday\fi}}

\endinput

%
% --- Likewise, \phaseofmoon inserts the phase of the moon into the
% --- text. This was written by the same person as \dayofweek.
% --- The routine calculates the year's epact (the age of the moon on Jan 1.),
% --- adds this to the number of days in the year, and calculates the phase
% --- of the moon for this date.  It returns the phase as a string, e.g.,
% --- \NewMoon, \FullMoon, etc.
%
% --- In the algorithm:
% ---      diy       is the day of the year - 1 (i.e., Jan 1 is day 0).
% ---      golden    is the number of the year in the Mentonic cycle, used to
% ---                determine the position of the calender moon.
% ---      epact     is the age of the calender moon (in days) at the beginning
% ---                of the year.  To calculate epact, two century-based
% ---                corrections are applied:
% ---                Gregorian:      (3 * cent)/4 - 12
% ---                      is the number of years such as 1700, 1800 when
% ---                      leap year was not held.
% ---                Clavian:      (((8 * cent) + 5) / 25) - 5
% ---                      is a correction to the Mentonic cycle of about
% ---                      8 days every 2500 years.  Note that this will
% ---                      overflow 16 bits in the year 409600.  Beware.
% --- The algorithm is accurate for the Gregorian calender only.
%
% --- The magic numbers used in the phase calculation are:
% ---      29.5            The moon's period in days.
% ---     177              29.5 scaled by 6
% ---      22              (29.5 / 8) scaled by 6 (this gets the phase)
% ---      11              ((29.5 / 8) / 2) scaled by 6
%
% --- Theoretically, this should yield a number in the range 0 .. 7.  However,
% --- two days per year, things don't work out too well.
%
% --- Epact is calculated by the algorithm given in Knuth vol. 1 (Calculation
% --- of Easter).  See also the article on Calenders in the Encyclopaedia
% --- Britannica and Knuth's algorithm in CACM April 1962, page 209.
%
\def\phaseofmoon#1#2#3{{%
  \@diy=#3 \advance\@diy by \ifcase#2                  % Jan 1 == 0
      -1\or -1\or 30\or 58\or 89\or 119\or 150\or      % Jan .. Jun
      180\or 211\or 241\or 272\or 303\or 333\fi        % Jul .. Dec
%            if ((month > 2) && ((year % 4 == 0) &&
%                ((year % 400 == 0) || (year % 100 != 0))))
%                  diy++;            /* Leapyear fixup      */
  \ifnum #2>2
    \@x=#1 \@y=\@x \divide\@y by 4 \multiply\@y by 4 \advance\@x by -\@y
    \ifnum \@x=0                    % month > 2 and maybe leap year
      \@x=#1 \@y=\@x \divide\@y by 400 \multiply\@y by 400 \advance\@x by -\@y
      \ifnum \@x=0                  % 2000 is a leap year
      \advance\@diy by 1            % so it's one day later
      \else                         % not 2000, check other '00's
      \@x=#1 \@y=\@x \divide\@y by 100 \multiply\@y by 100 \advance\@x by -\@y
      \ifnum \@x>0                  % not some other '00' year
          \advance\@diy by 1        % it's still one day later
      \fi                           % not odd century
      \fi                           % not 2000-type century
    \fi                             % not leapish year
  \fi                               % not march or later
%            cent = (year / 100) + 1;      /* Century number */
%            golden = (year % 19) + 1;      /* Golden number */
  \@cent=#1 \divide\@cent by 100 \advance\@cent by 1
  \@golden=#1
  \@y=#1 \divide\@y by 19 \multiply\@y by 19 \advance\@golden by -\@y
  \advance\@golden by 1
%            epact = ((11 * golden) + 20        /* Golden number */
%            + (((8 * cent) + 5) / 25) - 5      /* 400 year cycle */
%            - (((3 * cent) / 4) - 12)) % 30;   /* Leap year correction */
  \@epact=11 \multiply\@epact by \@golden
  \advance\@epact by 20
  \@x=8 \multiply\@x by \@cent \advance\@x by 5
  \divide\@x by 25 \advance\@x by -5
  \advance\@epact by \@x
  \@x=3 \multiply\@x by \@cent \divide\@x by 4 \advance\@x by -12
  \advance\@epact by -\@x
  \@y=\@epact \divide\@y by 30 \multiply\@y by 30 \advance\@epact by -\@y
%      if (epact <= 0)
%            epact += 30;                  /* Age range is 1 .. 30 */
%      if ((epact == 25 && golden > 11) || epact == 24)
%            epact++;
  \ifnum \@epact<0
    \advance\@epact by 30
  \fi
  \ifnum \@epact=25
    \ifnum \@golden>11
      \advance \@epact by 1
    \fi
  \else
    \ifnum \@epact=24
      \advance \@epact by 1
    \fi
  \fi
%
% --- Calculate the phase, using the magic numbers defined above.
% --- Note that phase may be equal to 8 (== 0) on two days of the year
% --- due to the way the algorithm was implemented.
% ---      phase = (((((diy + epact) * 6) + 11) % 177) / 22) & 7;
%
  \@x=\@diy \advance\@x by \@epact \multiply\@x by 6 \advance\@x by 11
  \@y=\@x \divide\@y by 177 \multiply\@y by 177 \advance\@x by -\@y
  \divide\@x by 22
  \ifcase\@x \NewMoon\or \WaxCresMoon\or \FirstQuarterMoon\or
      \WaxGibMoon\or \FullMoon\or \WaneGibMoon\or
      \LastQuarterMoon\or \WaneCresMoon\or \NewMoon\fi}}

REVISION HISTORY

1.00--0   3-Aug-1990  First version
1.00--1   4-Aug-1992  Corrected \dayofweek: it was generating
                      additional spaces before the day-name: this was
                      significant in {tabular} environments, and
                      screwed up alignment no end.  Disabled the
                      \phaseofmoon definitions, which are of little
                      interest to most people.

% --- End of dates.sty