% --- ------------------------------------------------------------------ % --- 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