Rata Die Implementation Examples

6.2.0 Notation

[x] = the greatest integer that does not exceed x. For example, [-1.5]=-2. This is sometimes called the floor function (for example in C/C++).

INT(x) = [x] NOTE: some computer languages have a different definition.

FIX(x) = the number x without its fraction. For example, FIX(-1.5)=-1

x\y = FIX(x/y)

6.2.1 Rata Die Number to Gregorian Date

1. The following sequence calculates Gregorian year Y, month M, and day D from Rata Die number RD. It uses real arithmetic.

Z = RD + 306
G = Z - .25
A = INT(G / 36524.25)
B = A - INT(A / 4)
year = INT((B+G) / 365.25)
C = B + Z - INT(365.25 * year)
month = FIX((5 * C + 456) / 153)
day = C - FIX((153 * month - 457) / 5)
IF month > 12 THEN
year = year + 1
month = month - 12
END IF

• The range of years that are supported is only limited by the word size of the implementation.
• Although FIX((5*C + 456)/ 153) and FIX((153*M - 457)/5) are elegant expressions, the use of indexed arrays are usually a faster implementation.
• Some languages only implement, within the language proper, the greatest integer function for a real argument. One can, of course, always create this function as part of the program itself.

2. The following sequence calculates Gregorian year Y, month M, and day D from Rata Die number RD. It uses integer arithmetic.

Z = RD + 306
H = 100*Z - 25
A = INT(H / 3652425)
B = A - INT(A / 4)
year = INT((100*B+H) / 36525)
C = B + Z - 365 * year - INT( year/4)
month = FIX((5 * C + 456) / 153)
day = C - FIX((153 * month - 457) / 5)
IF month > 12 THEN
year = year + 1
month = month - 12
END IF

• The range of years that are supported is only limited by the word size of the implementation.
• The greatest integer function can be replaced by integer division if RD > March 1 of the year zero.
• Although FIX((5*C + 456)/ 153) and FIX((153*M-457)/5) are elegant expressions, the use of indexed arrays are usually a faster implementation.
• Some languages only implement the greatest integer function for a real argument.

3. The following sequence calculates Gregorian year Y, month M, and day D from Rata Die number RD. It uses integer division and the shift right operator to effect integer division by powers of 2.

****WARNING*** Only valid for RD greater than or equal to -305 (March 2 of the year zero).

Z = RD + 306
H = 100*Z - 25
A = H \ 3652425)
B = A - SHIFTRIGHT(A,2)
year = (100*B+H)) \ 36525
C = B + Z - 365 * year - SHIFTRIGHT( year,2)
month = SHIFTRIGHT((535*C + 48950),14)
day = C - SHIFTRIGHT( (979*M-2918),5)
IF month > 12 THEN
year = year + 1
month = month - 12
END IF

• Only valid for RD greater than -306 (March 1 of the year zero).
• Although SHIFTRIGHT((535*C + 48950),14) and SHIFTRIGHT( (979*M-2918),5) are elegant expressions, the use of indexed arrays are usually a faster implementation.

4. QBASIC Implementation as a subroutine - using real arithmetic:

Note: & indicates 32-bit (long) integer and # indicates double precision real

SUB inrata (rd AS LONG, year AS LONG, month AS INTEGER, day AS INTEGER)
'INPUT: rd = Rata Die Number
'OUTPUT: Gregorian year, month, and day
'standard real arithmetic
Z& = rd + 306 'Day 1 is on January 1 of the year 1
G# = Z& - .25#
A& = INT(G# / 36524.25#) 'whole centuries
B& = A& - INT(A& / 4#) 'Julian days in whole centuries - 0.25
year = INT((G# + B&) / 365.25#)
C& = Z& + B& - INT(365.25 * year)'days in the year
month = (5 * C& + 456) \ 153
day = C& - ((153 * month - 457) \ 5)
IF month > 12 THEN 'convert to year that starts January 1
year = year + 1
month = month - 12
END IF 'convert to year that starts January 1
END SUB

5. QBASIC Implementation as a subroutine - Integer arithmetic version:

SUB inrata2 (rd AS LONG, year AS LONG, month AS INTEGER, day AS INTEGER) 'INPUT: rd = Rata Die Number 'OUTPUT: Gregorian year, month, and day
'***WARNING*** ONLY VALID IF RD > -306 (March 1 of year zero)
'INPUT: rd = Julian Day Number
'OUTPUT: Gregorian year, month, and day
Z& = rd + 306 'Day 1 is on March 1 of the year 0
H& = 100*Z& - 25
A& = H&\3652425 'whole centuries
B& = A& - A&\4 'adjustment to find the Julian days in whole centuries
year = (100*B&+H&) \ 36525
C& = B& + Z& - 365 * year - year\4 'days in the year
month = (5 * C& + 456) \ 153
day = C& - (153 * month - 457) \ 5
IF month > 12 THEN 'convert to year that starts January 1
year = year + 1
month = month - 12
END IF 'convert to year that starts January 1
END SUB