Algorithm to Calculate Calendar Number for any given Year

General Concept

The background for this algorithm is as follows:

The Algorithm

Step 3, below, uses CALGO 199 (this link is to a PDF file which requires the Adobe Acrobat Reader) from "Collected Algorithms from CACM".

1. Determine if year is 2- or 4-digits and correct if necessary. Ideally, the Year will be 4-digit, otherwise possible year range will be restricted to 1920 to 2019 using the 'cutoff' value shown.

    cutoff = 20         ' Arbitary pivot year (1920)

    if year < 100 then  ' year only consists of last 2-digits
        if year < cutoff then
            year = 2000 + year
        else            ' year >= cutoff
            year = 1900 + year
        end if
    end if

2. Determine if year is a leap year or not, after converting to 4-digits.

    Leap Year = False   ' Assume not a Leap Year to start
    Factor    = 0       ' Factor is amount to add to Day Index to
                        ' give Calendar Number assuming leap year
                        ' result remains 'False'

    if right (year, 2) = 0 then
        ' If century year and divisible by 400
        if (left (year, 2) mod 4) = 0 then
            Leap Year = True
            Factor    = 7
        end if
    else
        ' If not a century year and divisible by 4
        if (right (year, 2) mod 4) = 0 then
            Leap Year = True
            Factor    = 7
        end if
    end if

3. Determine the Day of the Week using one of the following methods:

    a.  Calculate Julian Day Number using CALGO 199 (JDAY)
            setting Year = Input Year; Month = 01; and, Day = 01
            as we want the day on which the first day of the year occurs
        Calculate Remainder Plus 1 using formula: (Julian MOD 7) + 1
        Determine Day of Week for result and adjust such that
            Sun = 1, Mon = 2, ..., Sat = 7
        We want the numeric value only for later and Sunday must equal day #1

    b.  Use ANSI COBOL 89 Instrinsic Function (see examples below) to obtain
        the Julian day number instead of CALGO 199 (JDAY) and then proceed as
        for method 'a' above

            MOVE FUNCTION INTEGER-OF-DATE (yyyy0101) TO receiving-field
            MOVE FUNCTION INTEGER-OF-DAY  (yyyy001)  TO receiving-field

        Base date for ANSI Intrinsic Date Functions is 01-JAN-1601 which was a Monday
        which means that 1601 used calendar #2.

4. Determine the Calendar Number from the obtained data as follows:

    if Leap Year = False then
        Calendar Number = (Corrected) Day-Of-Week Number
    else
        Calendar Number = (Corrected) Day-Of-Week Number + Factor
    end if


Modifications to this page 1998-2010,
Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Australia License.
Permissions beyond the scope of this license may be available at http://pmyers.pcug.org.au/Copyright_Licence.htm