D'ni time conversion
The conversion of dates between D'ni and human calendars presents an unusual challenge to the student of D'ni history. While a great deal of information is available regarding human timekeeping systems and conversions, the information needed to relate these to the D'ni system has been difficult to find. In addition, many D'ni researchers are not familiar with the techniques for converting among human calendars, much less the techniques required to convert these to or from the D'ni (or Cavernian) calendar.
This article attempts to correct that situation by drawing together all available information on the D'ni timekeeping system and its relationship to human measures of time. While this information will be of particular interest to programmers who wish to implement calendar conversions, the techniques presented can easily be applied using a hand calculator, or formulas in a spreadsheet.
- 1 Human Timekeeping
- 2 D'ni Timekeeping
- 3 Calendar Conversion Factors
- 4 Calendar Conversion Algorithms
- 4.1 Required Functions
- 4.2 Gregorian Calendar Algorithms
- 4.3 Cavernian Calendar Algorithms
- 4.4 Cavernian/Gregorian Conversion Algorithms
- 5 Acknowledgements
- 6 References
Before delving into the D'ni timekeeping system, some background in human timekeeping is required.
The calendar of primary interest in this discussion is the Gregorian calendar, which was proclaimed by Pope Gregory in 1582 and is now universally used in western countries and in international commerce. A great deal of in-depth information on this calendar, as well as other human calendars, is available from Web articles such as Fact Index: Gregorian Calendar and the Fourmilab Calendar Converter. However, only a few basic facts are important for the purposes of this article.
The Gregorian calendar is based on an average solar year of 365.2425 days, divided into common years of 365 days and leap years of 366. The calendar can be extended to dates prior to its invention by following the calendars rules for determining leap years. This extension is known as the "proleptic" Gregorian calendar.
In common usage, the calendar is divided into two eras: an "AD" era that counts years forward from the year 1 AD, and a "BC" era that counts years backward from the year 1 BC, which is the year prior to 1 AD. In academic practice, the AD era is designated with the abbreviation "CE" (Common Era), and the BC era is designated "BCE" (Before Common Era). Among astronomers, however, all years are treated as part of the common era, and the year 1 BCE is considered the year 0 CE, while earlier years are given negative numbers. Thus, -1 CE = 2 BCE, -2 CE = 3 BCE, etc. This is important because it helps to simplify the calculation of the difference between two dates, which is a key part of the process of calendar conversion.
Because astronomers often need to do arithmetic with dates, they have invented another concept that is useful to our purpose. This is the idea of representing a date as a Julian day number, which is the number of days and fractions that have elapsed since noon on January 1, 4713 BCE. By storing dates in this form, the difference between two dates can easily be determined by simply subtracting their Julian day numbers. Julian day numbers are well suited to computer storage, and are easily converted to other calendar systems, including the Cavernian calendar.
Many programming languages and software packages, such as Microsoft Excel, use a similar system of representing date/time values as "serial numbers". However, most of those serial-number systems are based on a relatively recent date, such as January 1, 1900 CE, and many cannot handle dates prior to their base. The Julian-day system is able to handle dates over a range of more than 10 million years when using double-precision values, so it is easily able to account for any date in the 10,000-year history of the D'ni civilization.
One final concept of importance is that of the "mean solar tropical year", which is fully described by the Web article Fact Index: Tropical Year. The Gregorian average year length of 365.2425 days is a slight over-estimate of the time between vernal equinoxes, which is only one possible measure of the time required for the Earth to return to the same position along the path of its orbit (the ecliptic). A different estimate will result from choosing a different point on the ecliptic – other than the vernal equinox point – from which to measure. Astronomers have defined the mean solar tropical year as the average length of a year over all points on the ecliptic, which is about 365.2422 days. More precise estimates are available, but these vary depending on when the measurement was performed, and the time units (atomic time, universal time, etc.) used to perform the calculation.
The essentials of the D'ni timekeeping system were first documented by Cyan Worlds on their D'ni Time Web page. This information is also available on the D'ni FAQ page of the DRC web site, and in the D'ni time article. Some familiarity with base-25 arithmetic and the D'ni numbering system may be helpful in understanding the timekeeping system.
The D'ni equivalents to our year, month, and day are the hahr, vailee, and yahr. The plural forms of the calendar divisions are hahrtee, vaileetee, and yahrtee.
While the D'ni hahr is approximately the same length as our Gregorian year, they divide it into 10 segments (vaileetee) of equal length, unlike our 12 months of differing lengths. In addition, the Cavernian calendar does not require regular corrections equivalent to our leap years, so all hahrtee are of equal length. This greatly simplifies date calculations in that calendar.
As we further divide our days into hours, minutes, and seconds, so do the D'ni divide their yahrtee into smaller units. However, they use five divisions: the gahrtahvo, pahrtahvo, tahvo, gorahn, and prorahn – rather than our three divisions. These divisions are based on the natural cycle of the light-producing algae in the D'ni cavern, and on the D'ni base-25 numbering system.
The D'ni apparently used only the pahrtahvotee (the D'ni "hour") in casual daily life, numbering them from 1 to 25 on their public clocks, which are known as "gorahyantee" in the D'ni language. However, this unit of time was not mentioned in any Cyan or DRC description of the system until March 2007, when a timekeeping brochure was placed in the classrooms of neighborhoods with clocks. The pahrtahvo was still not mentioned on the DRC web site as of December 2007. Because of this omission, exact times of day are usually given using only the gahrtahvo, tahvo, gorahn, and prorahn. (We do not presently know if this was also the D'ni practice when more precise times were required.) That convention is followed in the remainder of this document, and the pahrtahvo will not be discussed further.
The D'ni also recognized a larger unit of time – a sort of D'ni century – known as the hahrtee fahrah. This is a span of 100 hahrtee in base 25 (100), or 625 years in surface terms. Dates found in various journals often express the hahr in a shorthand form relative to the current hahrtee fahrah, much as we might use only the last two digits of the year and omit the century when writing a date. The current hahrtee fahrah began in 9375 DE, which is written as [15|0|0] in base 25. (This would be the first hahr of the 16th hahrtee fahrah, because the Cavernian dating system begins with hahr zero.) Add the shorthand year to the starting year of the hahrtee fahrah to determine the full year. For example, a date of 101.1.5 in a document would represent Leefo 5, 9476 DE when written in its long form, assuming the document was written in the current hahrtee fahrah.
Calendar Conversion Factors
The equivalence factors for surface time given in the tables above are, unfortunately, far too imprecise to be useful for converting between the Cavernian and Gregorian calendars. Also, were are missing one other piece of vital information: a starting point. Just as we need to know that 0° Celsius is exactly equal to 32° Fahrenheit before we can convert temperatures between the two scales, we need to know of at least one date in the Gregorian calendar that is exactly equivalent to one particular Cavernian date, before we can convert between the calendars. Until recently, such a "rosetta date" has never been directly provided and the required factors had to be derived from indirect evidence.
|Official Dates for Leefo 1 (PDT)|
|1998||4/21 2:35:17 AM|
|1999||4/21 8:24:03 AM|
|2000||4/20 2:12:48 PM|
|2001||4/20 8:01:33 PM|
|2002||4/21 1:50:18 AM|
|2003||4/21 7:39:03 AM|
The times shown above are in Pacific Daylight Time, which is UTC-0700.
While the above list does not provide us with the equivalent D'ni hahr for each year, it does give us a figure for the length of the hahr: 31556925 seconds, or 365.2421875 days. This makes the D'ni hahr about the same length as our astronomical mean solar tropical year, which is why the Cavernian calendar includes no corrections equivalent to our leap years.
The time given for 1998 was originally believed by the author to be a transcription error, because it is one second off from the intervals shown in the rest of the list, so it was ignored in the above calculation. However, in light of new information, the deviation appears to be the result of a slight rounding error.
The actual conversion factor for the hahr was revealed by RAWA in October 2007 to be 31556925.216 seconds, or 365.24219 days, which was the length of the mean solar tropical year in 1995. Thus, the correct table of key factors is:
- 1 Hahr = 365.24219 days = 290 yahrtee
- 1 Yahr = (365.24219 / 290) = 1.25945582758621 days
- 1 Day = (1 / 1.25945582758621) = 0.793993705929756 yahrtee
If desired, precise conversion factors between other surface and D'ni time measures can be derived from the above, but these are all that are needed for the purpose of performing calendar conversions.
The evidence originally used to determine the correct Cavernian hahrtee matching the date in the table is more indirect. In April of 1997, Cyan revealed the Riven Journals Web site (now defunct) as a teaser site for the upcoming release of Riven: The Sequel to Myst. The opening of the site was first announced by Jim Stephenson, editor of the Unofficial Riven Homepage (also defunct) on April 22, two days after the beginning of the D'ni New Year in 1997. At about this time a Web cam in Cyan headquarters (Cyan Cam) showed an image of a cake that Cyan prepared to celebrate the event. Written on the cake in D'ni numerals was the base-25 number [15|11|3] (%!3), which is 9653 in base 10. Presumably, this was the number of the hahr that began on that D'ni New Year in 1997 CE.
Based on this reasoning and the assumed one-second error in the 1998 time value, the "rosetta date" for Cavernian/Gregorian calendar conversions was determined to be:
- 00:00:00:00, Leefo 1, 9654 DE = 9:35:18 UTC, April 21, 1998 CE
However the correct date of calendar convergence was disclosed in October 2007 to be the date/time stamp of the HyperCard Stack for the original MYST game: April 21, 1991 at 9:54 AM PS(D)T. Thus:
- 00:00:00:00, Leefo 1, 9647 DE = 16:54:00 UTC, April 21, 1991 CE
Note that the surface time has been corrected from Pacific Standard (actually Daylight) Time, as supplied by RAWA, to Coordinated Universal Time (UTC, aka GMT). For purity's sake, it might be more appropriate to use Mountain Daylight Time (UTC-0600), which applies to the state of New Mexico under which the D'ni cavern lies. However, the use of UTC makes it easier for individuals to apply their own local time-zone corrections.
With conversion factors and convergence date in hand, we can proceed to a description of the specific calculations involved.
Calendar Conversion Algorithms
The following algorithms require the use of two functions, defined as follows:
INT(x) = the greatest integer that does not exceed x. For example, INT(1.5) = 1, and INT(-1.5) = -2. FIX(x) = the value of x with the fractional portion removed. For example, FIX(1.5) = 1, and FIX(-1.5) = -1.
Different programming languages may have different functions that perform these operations. For example, the INT function is known as the FLOOR function in some languages. The FIX function is sometimes known as the TRUNC function. Check the language reference for your programming language to be sure that you use the proper functions.
Gregorian Calendar Algorithms
The first two algorithms needed are those that convert Gregorian calendar dates to and from a version of the Julian day number. The algorithms are based on those provided by Peter Baum in an excellent article that gives the complete derivation of each algorithm, as well as implementation examples. The following algorithms differ from Baum's only in that the step of adding or subtracting the Julian base date of 1721118.5 is omitted, as this portion of the calculation is not needed for the purpose of Cavernian calendar conversion. The Julian Day used by these algorithms will be the number of days and fractions elapsed since midnight of the Gregorian date March 1, 0 CE. (Days are assumed to begin at the midnight that falls between the previous and current day, rather than at noon, as astronomers prefer.) No effort is made to account for leap seconds.
Algorithm 1. Gregorian Date to Julian Day Number
Assume a Gregorian date given as Day, Month, and Year, with optional time (on a 24-hour clock) given as Hour, Minute, and Second. All values are assumed to be integers.
A. If the era of the date is BCE, convert the year to a CE year:
Year = -(Year - 1)
B. If the month is January or February, treat it as month 13 or 14 of the previous year. This step ensures that any leap days in the period fall at the end of a "year".
if Month < 3 then Month = Month + 12 Year = Year - 1 end if
C. Calculate the number of whole days (WD: an integer) that have elapsed. This is the number of days accounted for by the number of years that have passed, adjusted for leap days, plus the number of days accounted for by prior months in the current year, plus the day of the current month.
WD = Day + FIX(((153 * Month) - 457) / 5) + INT(365.25 * Year) - INT(0.01 * Year) + INT(0.0025 * Year)
D. Calculate fractional day (FD: a real number), if necessary. This is the time of day in seconds, expressed as a fraction of the total number of seconds in a day. If no time is included in the conversion, let FD = 0.
FD = ((Hour * 3600) + (Minute * 60) + Second) / 86400
E. Calculate Julian Day (JD: a real number) as:
JD = WD + FD
Algorithm 2. Julian Day Number to Gregorian Date
Using real arithmetic, calculate Gregorian Year, Month, Day, Hour, Minute, and Second from a Julian Day (JD) that was calculated according to Algorithm 1. The input JD is assumed to be a real number. Output values are assumed to be integers.
A. Extract the number of whole days and calculate the date:
Z = INT(JD) G = Z - 0.25 A = INT(G / 36524.25) B = A - (0.25 * A) Year = INT((G + B) / 365.25) C = Z + B - INT(365.25 * Year) Month = FIX(((5 * C) + 456) / 153) Day = C - FIX(((153 * Month) - 457) / 5)
B. If the month is 13 or 14, adjust the month and year to a January-1 starting point:
if Month > 12 then Year = Year + 1 Month = Month - 12 end if
C. The year is in CE form, meaning that years prior to 1 CE will be 0 or negative. To change such years to BCE form, use the calculation shown below. If this conversion is used, the program should include a variable indicating whether the date is CE or BCE.
if Year < 1 then Year = 1 - Year
D. If JD includes a fractional (time of day) part, extract the fraction and calculate the time:
Z = (JD - INT(JD)) * 86400 Hour = FIX(Z / 3600) R = Z - (Hour * 3600) Minute = FIX(R / 60) Second = R - (Minute * 60)
Cavernian Calendar Algorithms
The next two algorithms needed are the Cavernian-calendar equivalents of the two algorithms above. We must be able to convert Cavernian date/time values to and from what I shall call the Atrian yahr number (named in honor of Atrus, son of Gehn), which is the number of yahrtee and fractions that have elapsed since a given base date. We will use Leefo 1, 9647 DE as our base for these algorithms, rather than Leefo 1, 0 DE, since this will simplify later conversions to and from the Gregorian calendar. (Yahrtee are assumed to begin at the "midnight" – 00:00:00:00 gahrtahvotee– that falls between the previous and current yahr.)
Algorithm 3. Cavernian Date to Atrian Yahr Number
Assume a Cavernian date given as Yahr, Vailee, and Hahr, with optional time given as Gahrtahvo, Tahvo, Gorahn, and Prorahn. All values are assumed to be integers.
A. Calculate the number of whole yahrtee (WY: an integer) that have elapsed. This is the number of yahrtee accounted for by the number of hahr that have passed, plus the number of yahrtee accounted for by prior vaileetee in the current hahr, plus the yahr of the current vailee.
WY = Yahr + ((Vailee - 1) * 29) + ((Hahr - 9647) * 290)
B. Calculate fractional yahr (FY: a real number), if necessary. This is the time of yahr in prorahntee, expressed as a fraction of the total number of prorahntee in a yahr. If no time is included in the conversion, let FY = 0.
FY = ((Gahrtahvo * 15625) + (Tahvo * 625) + (Gorahn * 25) + Prorahn) / 78125
C. Calculate Atrian Yahr (AY: a real number) as:
AY = WY + FY
Algorithm 4. Atrian Yahr Number to Cavernian Date
Using real arithmetic, calculate Cavernian Hahr, Vailee, Yahr, Gahrtahvo, Tahvo, Gorahn, and Prorahn from an Atrian Yahr (AY) that was calculated according to Algorithm 3. The input AY is assumed to be a real number. Output values are assumed to be integers.
A. Extract the number of whole yahrtee and calculate the date:
Z = INT(AY) G = Z - 0.25 A = INT(G / 290) Hahr = 9647 + A C = Z - (A * 290) Vailee = INT((C - 0.25) / 29) + 1 Yahr = C - ((Vailee - 1) * 29)
B. If AY includes a fractional (time of yahr) part, extract the fraction and calculate the time:
Z = (AY - INT(AY)) * 78125 Gahrtahvo = FIX(Z / 15625) R = Z - (Gahrtahvo * 15625) Tahvo = FIX(R / 625) R = R - (Tahvo * 625) Gorahn = FIX(R / 25) Prorahn = R - (Gorahn * 25)
Cavernian/Gregorian Conversion Algorithms
With Julian Day and Atrian Yahr numbers firmly in hand, the conversion between the Cavernian and Gregorian calendars becomes extremely simple, as shown in the final two algorithms.
Algorithm 5. Cavernian Date to Gregorian Date
A. Calculate the Atrian Yahr (AY) for the Cavernian date, as per Algorithm 3.
B. Using real arithmetic, determine the difference (AYD) between the AY of the selected date and the AY of the base Cavernian date for the conversion (which is 1.0). This gives the elapsed time in yahrtee and fractions.
AYD = AY - 1.0
C. Using real arithmetic, convert AYD from yahrtee to days to get the Julian Day difference (JDD). Add JDD to the Julian Day number of the base Gregorian date (which is 727249.704166666) to get the Julian Day number (JD) of the Cavernian date.
JDD = AYD * 1.25945582758621 JD = JDD + 727249.704166666
D. Convert the calculated Julian Day to a Gregorian date, as per Algorithm 2.
Algorithm 6. Gregorian Date to Cavernian Date
A. Calculate the Julian Day (JD) for the Gregorian date, as per Algorithm 1.
B. Using real arithmetic, determine the difference (JDD) between the JD of the selected date and the JD of the base Gregorian date for the conversion (which is 727249.704166666). This gives the elapsed time in days and fractions.
JDD = JD - 727249.704166666
C. Using real arithmetic, convert JDD from days to yahrtee to get the Atrian Yahr difference (AYD). Add AYD to the Atrian Yahr number of the base Cavernian date (which is 1.0) to get the Atrian Yahr number (AY) of the Gregorian date.
AYD = JDD * 0.793993705929756 AY = AYD + 1.0
D. Convert the calculated Atrian Yahr to a Cavernian date, as per Algorithm 4.
This article is © 2004, 2007 by Brett Middleton, and may be freely distributed without permission, provided that proper attribution is given.
Special thanks are due to Khrees of the DLF, Gadren of the Myst/Uru Obsession forum, and Alahmnat for providing much useful information. Extra-special thanks are due to RIUM+, who pestered RAWA into finally releasing exact conversion information in October 2007.