MathSource Reviews

Calendars, Time, and Dates in Mathematica

Edited by Matthew M. Thomas

This MathSource review begins the fourth year of these reviews in this journal. As such, it might be appropriate to update concepts examined in past reviews. In that vein, note this: Recent Mathematica literature offers treatments of weighted voting systems [Tannenbaum 1997] examined here in issue 4(3), and of Spirograph(TM) output generation [Lee 1996] examined here in issue 3(1). But perhaps it would be more timely, on the third anniversary of these reviews, to explore that which alerts one to an anniversary's occurrence–the calendar. This review examines the calendar, time, and date functions, notebooks, and packages available through MathSource.

Background

The year: 1977 A.D. The scene: An episode of the American Broadcasting Company's situation comedy "Barney Miller." Detective Stanley Wojehowicz [proper spelling vigorously debated in rec.arts.tv Usenet newsgroup posts] sits at his typewriter, pecking in information he receives from a middle-aged woman who may or may not have full use of her mental faculties. (Same may or may not be said of Detective Wojehowicz.)	

"Age?"	"Sixty-one."	Right forefinger presses "6" key; left does same to "1" key.	

"I was forty-five in '61."	Flustered, the detective whites out "61" from the form. Having no access to abacus, computer, or Mathematica 3.0, he resorts to his fingers to calculate the age (in 1977) of a woman aged 45 years in 1961. The result and a realization of wasted effort simultaneously arrive:

	"That makes you 61!"	In this regard, the good detective would have benefitted from items MathSource offers. Those items will be examined in due course; let us first make a cursory examination of well-known calendars.

Julian calendar

Where to begin such an examination? Let us arbitrarily choose the 304-day, 10-month calendar of Romulus, wolf-suckled mythical founder of Rome. Numa Pompilius, Rome's second king, added fifty days to it, to coordinate this lunar calendar with the solar year. The resulting twelve-month calendar was the best approximation to a solar-seasonal year into which a whole number of lunar synodic months would fit. By 150 B.C., another day was added to this calendar, creating the 355-day year [Aveni, 1995]. But this modified calendar relied heavily upon intercalation–the shoehorning of additional days into the calendar year–to keep the months in step with the lunal phases and the year in sync with the seasons. Fixed rules for intercalation were not in place, and intercalation was performed inconsistently. The result: A vernal equinox on the Ides of May in 50 B.C. [Ronan 1995].

	With intercalation more art than science, and with winter ending but a fortnight before June, action had to be taken. And so it was that in 46 B.C. (year 709 of Rome), Alexandrian astronomer Sosigenes proposed (and Julius Causar accepted) a fix and an abandonment of the Roman calendar. Accordingly, 46 B.C. suffered Two intercalations—a standard 23-day insertion after 23 February 46 B.C., and an unusual 67-day insertion between November and December to align the calendar with the equinoxes. Thus, 46 B.C., the months (365 days) was introduced. This new calendar, unlike its Roman predecessor but similar to the Egyptian calendar, was a solar-seasonal calendar. To make its average year 365.25 days, a 366th day was appended to February every four years. We know the resulting calendar as the Julian calendar.	
	
	Julius Caesar was assassinated in 44 B.C. Perhaps in anticipation of modern recording artist Jimmy Buffett's "Living Life in Three-Quarters' Time," the calendar-keepers began inserting the leap day every three years instead of every four.  In 9 B.C., Caesar Augustus restored order by suspending leap years for sixteen years. It was not until 8 A.D. that the Julian calendar began to function with regularity [Bickerman, 1980]. Once on track, this calendar was in force for 1 1/2 millenia.

Gregorian calendar

In 730 A.D., Anglo-Saxon monk St. Bede the Venerable of Jarrow proclaimed the 365.25-day Julian year 11 minutes 14 seconds longer than the solar year [Famighetti, 1995, p. 309]. That's an error of only one day every 128 years, but just as the vernal equinox once encroached upon June, so it was that Easter Sunday began falling later and later in the spring season. The Easter warming caught the Vatican's attention, and in December 1545 A.D., the Council of Trent authorized Pope Paul III to take corrective action. Nonetheless, it wasn't until the efforts of Jesuit astronomer Christopher Clavius and Vatican librarian Luigi Lilio (Aloysius Lilius in some parts) that acceptable corrective action was available. This action was taken in 1582 by Pope Gregory XIII, who 1) added ten days to the Julian calendar–the 15 October 1582 A.D. sunrise followed the 4 October sunset, 2) set the solar year at 365.2422 days, 3) decreed that only those century-closing years exactly divisible by 400 would be leap years (1600, 2000, 2400, ... but not 1700, 1800, 1900, ...), and 4) set Easter on the Sunday following the (Paschal) Full Moon occurring on/after the vernal equinox [Ronan 1995]. So came to be the Gregorian calendar, whose 365.2425 days per year make it accurate to one day every 3333 years 4 months. 	

	The Julian and Gregorian calendars coincided in 300 A.D.: before then, the former led the latter by three days every 400 years (29 December 102 B.C. Gregorian is 1 January 101 B.C. Julian); since then, the former lags the latter by the same period [Bickerman 1980]. Most Catholic countries adopted the Gregorian calendar in the late 16th century. Denmark and the Dutch and German Protestant states adopted it in the late 17th century. Britain and her colonies did so in 1752; Sweden, in 1753; Japan, 1873; Egypt, 1875; Albania, Bulgaria, China, Estonia, Latvia, Lithuania, Romania, and Turkey, 1912-1917; the Soviet Union, 1918; Greece, 1923 [Ronan 1995]. Switzerland began adoption proceedings in 1583 and completed them in 1812–a duration consistent with its haste in accepting women's suffrage, no doubt. Alaska went Gregorian 130 years ago, upon its transfer from Russia to the United States. Of course, the longer a country waited before adopting the Gregorian calendar, the more days it had to add upon conversion. In Brittania, for example, 2 September 1752 was followed by 14 September: George Washington saw his 21st birthday move from 11 February to 22 February.
	
	Subsequent Gregorian calendar reforms included removal of leap-year status from century-closing years 4000, 8000, and 12,000 A.D. At an Eastern Orthodox congress in Constantinople in 1923, the century-closing rule was revised: Century-closing years would now be leap years only if, upon division by 900, a remainder of 200 or 600 resulted. This revision retains 2000 and 2400 as the only century-closing leap years for the next 800 years, and creates a 365.2422222\(TraditionalForm\`2\&_\)-day year ... accurate to one day in 45,045 years [Aveni 1995].  A scheme calling for eleven century-closing leap years every fifty millenia would meet the Gregorian-standard 365.2422-day solar year to all four decimal places, but that scheme comes with a whiff of overkill: Other bodies in the solar system induce gravitational disturbances on the earth, thus subtly altering the length of its solar year.
		
	(A closing note on the Gregorian calendar, to unnerve and prod Mathematica advocates ailing from triskaidekaphobia: In this, the thirteenth MathSource review, be it noted that in the calendar of the thirteenth Pope Gregory, it was found by a 13-year old [Baxter, 1969] that the thirteenth day of a Gregorian month was most likely to fall on–of all days of the week–a Friday. Be it also noted that precocious Master Baxter made or published said discovery while matriculating at Eton, as either a predecessor or a contemporary of precocious Master Stephen Wolfram.)

Islamic, Jewish, and other calendars

The Islamic calendar traditionally comprises twelve months, each dating from one crescent moon to the next. It is a lunar calendar, and since sightings of the moon vary with latitude and longitude, so does this calendar. As with the Jewish calendar, the Islamic calendar days run from sunset to sunrise; as with the Gregorian calendar, however, there are seven days to a week. The Islamic Era begins on the first day of the Arabic year in which the Hegira of Muhammed took place. That year, 1 A.H., corresponds to 16 July 622 A.D., for that was the day on which the Hegira of Muhammed (the emigration from Mecca to Medina) began. The Islamic calendar has approximately 354 days in its year, so translating its dates into solar calendar dates is not straightforward. One Gregorian-to-Islamic translation formula calls for subtracting 622 from the Gregorian date, then adding the "total of the Gregorian date minus 622 divided by 32 ... [but] this formula is somewhat inaccurate, and it is thus better to consult a conversion table" [Schubel 1995]. We are now in year 1417 A.H. of the Islamic calendar.	

	The Jewish calendar is lunisolar, with the moon governing the months and the sun the year. Intercalation is a necessary staple of this calendar, lest the same fate befall Jewish festivals that befell Easter in Gregory XIII's day and the vernal equinox during Julius Caesar's. In this case, intercalation takes the guise of a month–Adar II or Adar Sheni–added in years 3, 6, 8, 11, 14, 17, and 19 of the 19-year lunar cycle. Rosh Ha-Shanah (New Year's Day) is fixed in accordance with four decidedly non-trivial criteria involving Yom Kippur, Hoshana Rabba, specific days of the week, and other factors [Wiesenberg, 1971]. We are now in year 5757 A.M. of the Jewish calendar. Just as a conversion table benefits Gregorian-to-Islamic date translation, so does a Gregorian-Jewish combination calendar offer equivalent benefits. Volume 1 of Encyclopaedia Judaica [1972] presents such a calendar, covering Gregorian years 1920 - 2020 A.D (Jewish years 5680 - 5780 A.M.).	
	
	The International Fixed Calendar and the World Calendar have been presented as new calendars for the modern age. The former comprises thirteen months of 28 days each (surely to the delight of triskaidekaphobics everywhere), with an additional day at the end of the year. The latter comprises four quarters of 91 days each. Each has an intercalation scheme for leap day insertion [Ronan, 1995]. There are said to be advantages to each strategy. One might surmise, however, that a calendar change would be as welcomed by the masses as, say, a 67-day intercalation between November and December by Santa-fixated children on Thanksgiving day.

Year 2000 and beyond

No discussion of calendars would be complete without a mention of the "year 2000 problem." Most business applications (payroll, accounts receivable, et al) are coded in primitive, workhorse languages such as COBOL and APL. The "year 2000 problem" is generally found within the working-storage sections of these COBOL programs, where templates for dates tend to use a MM/DD/YY format (following the U.S. convention of month/date/year). Note the allowance for only two–not four–year-related digits–a convention intended to save memory by sparing the program those redundant "19" digits. The convention does save memory, but creates a side-effect that is potentially disastrous: Programs following this convention, given but two digits for denoting the year, may now treat the day after 31 December 1999 as 1 January 1900, wreaking pure havoc on all date-related calculations. The woman in the aforementioned "Barney Miller" episode, aged 45 years in 1961 A.D., would be 84 in 2000 A.D. Nonetheless, come the last year in the second millenium A.D. ...

	woman: "I was born in '16."
	
	Wojehowicz [bemused]: "The computer says you're 16 years old!" 	
	
	A web site devoted to this problem has URL www.year2000.com. At that site are a number of papers, by Peter de Jager and others, discussing the consequences of ignoring this problem. One of the papers, a 6 September 1993 Computerworld article by de Jager, estimates that Fortune 50 companies must spend $0.35 to $0.40 per line of code–$50 million to $100 million total per company. A later paper, by David Loundy from the 14 November 1996 Chicago Daily Law Bulletin, places that cost at $1.02 to $8.52 per line of code–$358 million to $3 billion total for organizations such as the Department of Defense. Code alteration and testing incur these costs, which do not lessen as 2000 draws near. To dramatize the problem, this web site features a clock that counts down to midnight, 1 January 2000 A.D.
	
	The SPR company is one of many firms now hiring COBOL programmers to combat the year 2000 problem. Their web site, whose URL is www.sprinc.com/spr_home.htm, discusses this problem and also discusses Julian and Gregorian calendars (see www.sprinc.com/marktime.htm as of late January 1997). "Does twelve minutes seem like a lot of time to you?" begins the latter discussion, in reference to the discrepancy between the Julian calendar and the solar year. "Imagine that for an entire year you were twelve minutes early for your appointments. This would be a good thing right? Aren't we told to be early for our appointments – that it is courteous to be early and usually unacceptable to be late?" Indeed. Harlan Ellison's "'Repent, Harlequin!' Said the Ticktockman" [Ellison 1987] describes a world in which every twelve minutes of tardiness would cost you twelve minutes of your life. In 2389 A.D., when this penalty would per the story take effect, might the tools of the Master Timekeeper (the "Ticktockman") have their origin in what is now known as MathSource?

MathSource items

When we comb through MathSource at URL www.wolfram.com/mathsource/, we find three items pertaining to calendars et al. The first is "Time and Date routines" by Thomas Cool of the Netherlands, found at pub/Applications/Other/0208-156 and dated August 1995. This item comprises three documents: a Readme file (2 kB), the Time.m package (7 kB), and the Time.ma notebook (28 kB). The second is "TimeMath" by Jack Calman of Johns Hopkins, found at pub/Applications/Other/0208-369 and dated October 1996. This item comprises the TimeMath.ma notebook (9 kB). The third is "Calendar and Date Computations" by Ilan Vardi, whose Computational Recreations in Mathematica was published by Addison-Wesley in 1991. This item is found at pub/Enhancements/Other/0200-776, and comprises Calendar.m (16 kB), Documentation.txt (5 kB), and SampleInput.txt (431 bytes).

Time and Date routines

This item, submitted by Thomas Cool (cool@can.nl), is intended to supplement the standard Miscellaneous`Calendar` package by Ilan Vardi (about which more later). Material contained therein is intended to complement Decision Support and Genetic Programming packages, available at cost from Thomas Cool. He also requests that a $10 license be paid for using the Time.m package and the Time.ma notebook. This item works in conjunction with pub/Enhancements/System/0208-167, which contains items Readme.txt, Common_q.ma, Common.m, Context.m, Declare.m, List.m, Tool.m, Manager.m, and CoolPacs.m. Of these, only Context.m, Declare.m, Manager.m, and CoolPacs.m load (using the <<filename command) unaccompanied by a license-related message. That message is also displayed when Time.m is loaded.	The Time.m package contains a number of date format conversion routines, primarily designed to prepare these dates for input to other packages. To wit, for 30 January 1997:

AnyToCalendarDate[{1,30,1997}]

AnyToStandardDate[{1,30,1997}]

The StringToDate[ ] function converts 6-digit YYMMDD string input into the standard Mathematica date format. Note how the option allows for one to override the default year 1950:

StringToDate["000101"]

StringToDate["000101",First -> 1850]

A closely-related IntegerToDate[ ] function performs this conversion given an 8-digit YYYYMMDD string, or given a 6-digit YYYYMM string.	

	Other functions in Time.m (aside from those taken directly from the Miscellaneous`Calendar` package itself) include DateToDays[ ] and DaysToDate[ ]. In the Gregorian, Islamic, or Julian calendar system, the former converts the date, in {year, month, day} format, into a count of days since date {1, 1, 1} in the given calendar (most likely through using the standard function DaysBetween[{1,1,1},{y,m,d}] + 1). The latter performs the reverse operation. Yet other functions have purposefully been altered, so as not to perform properly in the absence of a license. To with, CoordiDate[{1995,9,15}] is supposed to return 1995.7, according to the documentation in Time.ma. Clearly, 1995.7 is a fractional representation of 15 September 1995. But when we run this function with this argument, we get the following:

CoordiDate[{1995,9,15}]

It does not take much in Mathematica to create a function equivalent to this one, especially given the Miscellaneous`Calendar` package from which to work. As such, the purpose for altering this function so as to render it inoperable is not clear.

TimeMath

Of the three items, this notebook is the most simple. It comprises two functions, TimeAdd[ ] and TimeBetween[ ]. Both deal with time in the format {year, month, day, hour, min, sec}; where all the variables are integers (and year is not limited to two digits, fortunately). The first adds an increment of time to a start date; the second subtracts a stop time from a start time. The functions are not profusely documented, but descriptions, examples, and error messages in conjunction with both functions are available. 	

	Here is TimeAdd:

TimeAdd[tstart_, dt_] :=
   If[tstart[[2]] == 0 || tstart[[3]] == 0, 
   Message[TimeAdd::MonthDayNumb],
   ToDate[FromDate[tstart] + 
   FromDate[{1900, 1, 1, 0, 0, 0} + dt]]]

Any year 2000 problem here?

TimeAdd[{1999,12,31,23,59,59},{0,0,0,0,0,2}]

No, fortunately: Two seconds after 11:59:59 pm on 31 December 1999 is indeed 12:00:01am on 1 January 2000. Now, what about leap day recognition? Here is what happens when we add one day to noon 28 February in three different years:

TimeAdd[{2000,2,28,12,0,0},{0,0,1,0,0,0}]

TimeAdd[{1900,2,28,12,0,0},{0,0,1,0,0,0}]

TimeAdd[{2800,2,28,12,0,0},{0,0,1,0,0,0}]

The year 2000 is indeed a leap year, while 1900 is indeed not one. The year 2800 is a leap year in the Gregorian scheme, but not in the 1923 Constantinople revision ... a revision not widely known and, probably, less widely accepted.	

	Here is TimeBetween:

TimeBetween[tstart_, tstop_] := 
	If[FromDate[tstop] > FromDate[tstart],
       ToDate[FromDate[tstop] - FromDate[tstart]] - 			ToDate[0], Message[TimeBetween::StopTime]]

Despite Peter de Jager's warnings, how much longer can I twiddle my thumbs before the year 2000 is upon me?

TimeBetween[Date[], {2000,1,1,0,0,0}]

The output (two years, ten months, and change) is accurate as of this writing. In Ellison's short story, the Master Timekeeper begins penalizing tardiness at midnight 15 July 2389. Upon welcoming the year 2000, how much longer can I disregard timetables before I lose time off my life?

TimeBetween[{2000,1,1,0,0,0}, {2389,7,15,0,0,0}]

Three-hundred eighty-nine more years must pass between the year 2000 celebration and my submitting my time-card and cardioplate for processing. We should live so long.

Calendar and Date Computations

This item is the standard Miscellaneous'Calendar' package by Ilan Vardi. As is expected from the standard packages, the accompanying documentation is thorough: Each available function is explained, and background discussion on the workings of well-known calendars is included. References (including some that are also cited in the Bibliography below) are cited in the documentation, such that interested users can pursue them if they wish. The SampleInput.txt file contains sample inputs to the Calendar.m package.	

	Functions available through the Calendar.m package are DayOfWeek[ ], DaysBetween[ ], CalendarChange[ ], EasterSunday[ ], EasterSundayGreekOrthodox[ ], and JewishNewYear[ ]. The user is cautioned that the Julian calendar functions are valid starting only in 4 A.D., while the Jewish New Year computations work only for Gregorian years between 1900 and 2100, inclusive. As such, we cannot use these functions to verify that . We can, however, investigate other dates.
	
	After loading Calendar.m, we can use these functions to determine the date the Hegira began, to confirm that the current Islamic year is 1417 A.H., to verify the Julian-to-Gregorian conversion dates for the Vatican and for the British empire, and to calculate Easter Sunday and  for 1997 A.D.

CalendarChange[{1,1,1},Islamic,Julian]

CalendarChange[Date[], Gregorian,Islamic]

CalendarChange[{1582,10,5},Julian,Gregorian]

CalendarChange[{1752,9,3},Julian,Gregorian]

EasterSunday[1997]

JewishNewYear[1997]

All seems well. Now, let us examine the days of the week fora would-be leap day:

DayOfWeek[{2100,2,29}, Calendar -> Gregorian]

Wait a second. The year 2100 is not a leap year in the Gregorian calendar; 29 February 2100 does not exist: The Time.m package (above) even returns False for LeapQ[2100, Calendar -> Gregorian], as it should. So why no error message? And how serious is this error? To answer the latter question, let us use the function on 28 February and 1 March of 2100 A.D.

DayOfWeek[{2100,2,28}, Calendar -> Gregorian]

DayOfWeek[{2100,3,1}, Calendar -> Gregorian]

Well, at least its assignment of a day to the nonexistent 29 February 2100 did not disturb the count of days. To verify that lack of disturbance, let us check the days between 28 February and 1 March of 2100:

DaysBetween[{2100,2,28},{2100,3,1}]

DaysBetween[{2100,2,27},{2100,2,28}]

The nonexistent leap day does not seem to be counted. The original error is definitely an error, but at least its effects are contained.

Summary

It may well be that the packages Thomas Cool has available for licensing are useful and worth the licensing prices he asks. Most of his packages now available through MathSource require a license to run; as such, trying to examine them through MathSource may not reveal the true breadth of their capabilities. Nonetheless, those functions that are made available license-free should entice the user to license the entire package–or at least a part thereof. In this case, the available functions fail to do so. They appear to offer list processing capabilities now widely available in Mathematica circles, as well as date processing capabilities independently available through the Miscellaneous`Calendar`  package. In addition, the documentation should better explain how the available functions operate, in the presence of and in the absence of a license. Exploration is free for most MathSource items, but when fees are involved, caveat emptor is the rule.
	
	The TimeMath item submitted by Jack Calman is by no means an elaborate notebook with extensive examples and illustrations. It is but a collection of a couple of functions that have their use in doing arithmetic with time. Still, it has a well-deserved home in MathSource, since it provides instructions, examples, and error messages for those functions. The notebook offers a template for those seeking to build more complicated functions involving time, as well as for those looking to submit simple but useful notebooks to MathSource.
	
	The standard package for calendar operations by Ilan Vardi is as one would expect a standard Mathematica package to be: Thoroughly documented and useful. It is a model for developers to follow in that regard. And although its functions cover only a limited range of time, they do seem to perform their tasks properly. The noteworthy exception is the DayOfWeek[ ] function, which happily returns a day even when nonexistent dates comprise the function input. Fortunately, the magnitude of that error appears to be contained, as it does not appear to affect the days-between-dates function adversely. Good thing, too, for a standard package.

REFERENCES

Aveni, A. F., Empires of Time: Calendars, Clocks, and Cultures, New York: Kodansha International, 1995.

Baxter, S. R., To Prove That the 13th Day of the Month Is More Likely to Be a Friday Than Any Other Day of the Week, The Mathematical Gazette, 53(384), 127-129, 1969.

Bickerman, E. J., Chronology of the Ancient World, 2nd ed., Ithaca, NY: Cornell University Press, 1980.

Ellison, H., "Repent, Harlequin!" Said the Ticktockman, (originally published in Galaxy Magazine, 1965) The Essential Ellison, Omaha, NE: NemoPress, 877-886, 1987.

Famighetti, R., ed., World Almanac and Book of Facts 1996, Mahwah, NJ: Funk & Wagnalls Corp., 1995."Hundred-Year Jewish Calendar, 1920-2020," Encyclopaedia Judaica, Vol. 1, G. Wigoder, ed., Jerusalem: Keter Publishing House, Ltd., 109-159, 1972.

Lee, X., "Trochoids, Hypotrochoids and Epitrochoids," Mathematica in Education and Research, 5(2), 37-41, 1996.

Ronan, C. A., "The Western Calendar and Calendar Reforms," The New Encyclopaedia Brittanica, Vol. 15 (Macropaedia), 429-432, 1995.

Schubel, V. J., "Islamic Calendar," The Oxford Encyclopedia of the Modern Islamic World, Vol. 2, J. L. Esposito, ed., Oxford: Oxford University Press, 301, 1995.

Tannenbaum, P., "Power in Weighted Voting Systems," The Mathematica Journal, 7(1), 58-63, 1997.

Wiesenberg, E. J., "Calendar," Encyclopaedia Judaica, Vol. 5, G. Wigoder, ed., Jerusalem: Keter Publishing House, Ltd., 43-44, 1971.()