%------------------------------------------------------------------------------ % d a t e s . s t y -- style file for inserting dates into documents %------------------------------------------------------------------------------ % DESCRIPTION % \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 `Saturday 14th 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 % % \dayofweek{year}{month}{day} generates the day of the week for % the given date % % \Sunday (etc) generates `Sunday' (etc) % \January (etc) generates 'January' (etc) % % \stsup generates a raised, reduced, underlined `st', as in 1st % \ndsup generates a raised, reduced, underlined `nd', as in 2nd % \rdsup generates a raised, reduced, underlined `rd', as in 3rd % \thsup generates a raised, reduced, underlined `th', as in 4th % \raiseul used by the above macros to raise and underline %------------------------------------------------------------------------------ % REVISION HISTORY % v1.00 1990-08-03 Adrian F. Clark % Original version. % v1.01 1992-08-04 Adrian F. Clark % 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. % v1.02 1994-05-13 Adrian F. Clark % Changed \@x and \@y to \dates@x and \dates@y to circumvent name clash % with bezier.sty. % v2.00 2002-03-07 Adrian F. Clark % \th -> \thsup (etc) to avoid name clash with \th (thorn) in PS fonts; % THIS IS AN INCOMPATIBILITY, alas. % Removed a few vestigates of the phase of the moon computation. % Revised comments. % v2.01 2003-08-14 Adrian F. Clark % Added \now to generate the time as "hh:mm". % v2.02 2003-11-15 Adrian F. Clark % \alien@up -> \raiseul %------------------------------------------------------------------------------ % TO-DO % I suppose it'd be nice to take an optional argument, the language in which % the text is to appear. For example, % \usepackage[french]{dates} % would make the dates appear in the form `Samedi 14 Octobre 1066'. Or maybe % this could be picked up from the babel option? %------------------------------------------------------------------------------ % Copyright 1990-2002 Adrian F. Clark All rights reserved. %------------------------------------------------------------------------------ %------------------------------------------------------------------------------ % The actual date macros. %------------------------------------------------------------------------------ % \today generates today's date in the style `Saturday 14th October 1066' \def\today{\thisdayofweek\ \thisdayth\ \thismonth\ \thisyear} \def\thisday{\number\day} \def\thisdayth{\thisday \ifcase\day \or\stsup\or\ndsup\or\rdsup\or\thsup\or\thsup \or\thsup\or\thsup\or\thsup\or\thsup\or\thsup \or\thsup\or\thsup\or\thsup\or\thsup\or\thsup \or\thsup\or\thsup\or\thsup\or\thsup\or\thsup \or\stsup\or\ndsup\or\rdsup\or\thsup\or\thsup \or\thsup\or\thsup\or\thsup\or\thsup\or\thsup \or\stsup\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} %------------------------------------------------------------------------------ % Names of days of the week and the months. This makes it easier to change % them for languages other than English (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} %------------------------------------------------------------------------------ % 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 and \dayofweek do all their register manipulations within a % group. This is 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 \def\dates@x{\count6 } % temp register \def\dates@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, including LaTeX2e, which uses % the font selection scheme due to Mittelbach and Sh\"oepf, such a hack is not % necessary. The macros detect which version is in use automagically. %------------------------------------------------------------------------------ \def\stsup{\raiseul{st}} \def\ndsup{\raiseul{nd}} \def\rdsup{\raiseul{rd}} \def\thsup{\raiseul{th}} \def\raiseul#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 time. %------------------------------------------------------------------------------ \def\@hour{\count0 } \def\@min{\count1 } \def\now{{\@hour=\time \@min=\@hour \divide\@hour by 60\relax \ifnum\@hour <10 0\number\@hour \else \number\@hour \fi :\relax \multiply\@hour by 60 \advance\@min by -\@hour \ifnum\@min <10 0\number\@min \else \number\@min \fi}} %------------------------------------------------------------------------------ % The nitty-gritty. %------------------------------------------------------------------------------ % The day of the week (\Sunday, etc.) is inserted into the text by % \dayofweek. (This uses registers \@dow, \@leap, \dates@x and \dates@y.) I % acquired this from elsewhere; it was apparently written by Martin Minow, now % a DEC employee. The algorithm 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 \dates@y=\@dow \divide\dates@y by 13\multiply\dates@y by 12\relax \advance\@dow by -\dates@y \multiply\@dow by 13\relax \advance\@dow by -1 \divide\@dow by 5\relax \advance\@dow by #3\advance\@dow by 77\relax \dates@x=\@leap \dates@y=\dates@x \divide\dates@y by 100\multiply\dates@y by 100\relax \advance\dates@x by -\dates@y \relax \multiply\dates@x by 5\divide\dates@x by 4\advance\@dow by \dates@x \dates@x=\@leap \divide\dates@x by 400\advance\@dow by \dates@x \dates@x=\@leap \divide\dates@x by 100\multiply\dates@x by 2\relax \advance\@dow by -\dates@x \dates@x=\@dow \divide\dates@x by 7\relax \multiply\dates@x by 7\advance\@dow by -\dates@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\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} \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 \dates@x=#1 \dates@y=\dates@x \divide\dates@y by 4 \multiply \dates@y by 4 \advance\dates@x by -\dates@y \ifnum \dates@x=0 % month > 2 and maybe leap year \dates@x=#1 \dates@y=\dates@x \divide\dates@y by 400 \multiply \dates@y by 400 \advance\dates@x by -\dates@y \ifnum \dates@x=0 % 2000 is a leap year \advance\@diy by 1 % so it's one day later \else % not 2000, check other '00's \dates@x=#1 \dates@y=\dates@x \divide\dates@y by 100 \multiply \dates@y by 100 \advance\dates@x by -\dates@y \ifnum \dates@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 \dates@y=#1 \divide\dates@y by 19 \multiply\dates@y by 19 \advance\@golden by -\dates@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 \dates@x=8 \multiply\dates@x by \@cent \advance\dates@x by 5 \divide\dates@x by 25 \advance\dates@x by -5 \advance\@epact by \dates@x \dates@x=3 \multiply\dates@x by \@cent \divide\dates@x by 4 \advance\dates@x by -12 \advance\@epact by -\dates@x \dates@y=\@epact \divide\dates@y by 30 \multiply\dates@y by 30 \advance\@epact by -\dates@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; \dates@x=\@diy \advance\dates@x by \@epact \multiply\dates@x by 6 \advance\dates@x by 11 \dates@y=\dates@x \divide\dates@y by 177 \multiply\dates@y by 177 \advance\dates@x by -\dates@y \divide\dates@x by 22 \ifcase\dates@x \NewMoon\or \WaxCresMoon\or \FirstQuarterMoon\or \WaxGibMoon\or \FullMoon\or \WaneGibMoon\or \LastQuarterMoon\or \WaneCresMoon\or \NewMoon\fi}} %------------------------------------------------------------------------------ % End of dates.sty %------------------------------------------------------------------------------