Figure 1: Routines to convert MMDDYYYY to/from (Mh)(Wh)DDYY

// file date.h
#include <stdio.h>
#include <string.h>
#include <stdlib.h> 
#include <ctype.h>

#define TRUE 1
#define FALSE 0
const int month_days [] = {
    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};

const int DigitsBasedOn64[] = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
    'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
    'y', 'z', '#', '$'
};

enum months {
    JANUARY = 1, FEBRUARY, MARCH, APRIL, MAY, JUNE, 
    JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, 
    DECEMBER
};  

enum days {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
    THURSDAY, FRIDAY, SATURDAY
};

enum fields
{
    MM, DD=2, CC=4, YY=6
}; 

// file date.c

////////////////////////////////////////////////////////////////
//  Function: FindCenturyDigits
//
//  Description: Finds a day of the week for a date in a given
//  century. Compares it with a day of the week for a date in
//  MWDDYY format.  If they are equal CC digits are returned.
//
//  Returns:  int CC digits if Ok, 0 -- otherwise
////////////////////////////////////////////////////////////////
int FindCenturyDigits(char *MWDDYYDate)
{
    char MWDDYYBuffer[7], MMDDCCYYBuffer[9],CCDigits[3];
    const int First400Start = 16;
    const int Second400Start = 20;
    const int Third400Start = 24;
    int i=0;
    int DayOfWeek; 

    strcpy (MWDDYYBuffer, MWDDYYDate);
    if(MWDDYYBuffer[1]>'6') {
        for(i=Second400Start;i<Third400Start;i++) {
            MWDDYYToMMDDCCYY(i,MWDDYYBuffer,MMDDCCYYBuffer); 
            DayOfWeek=FindDay(MMDDCCYYBuffer);

            // Add offset for dates in centuries after 20th 
            DayOfWeek+=7; 
            if (atoi(XDigitToDecimal(MWDDYYBuffer[1])) ==
                   DayOfWeek) {
                return SetCCDigits(MMDDCCYYBuffer, CCDigits); 
            }
        }        
    }
    else { // to count back centuries for efficiency
        for(i=(Second400Start-1);i>=First400Start;i--) {
            MWDDYYToMMDDCCYY(i,MWDDYYBuffer,MMDDCCYYBuffer);
            DayOfWeek = FindDay(MMDDCCYYBuffer);
            if((MWDDYYBuffer[1]-'0')==DayOfWeek) {
                return SetCCDigits(MMDDCCYYBuffer, CCDigits); 
            }
        }        
    }
    return (0); 
}    

////////////////////////////////////////////////////////////////
//  Function:  SetCCDigits
//  Description: Sets Century digits.
//  Returns: int CCDigitsPar converted to int.
////////////////////////////////////////////////////////////////
int SetCCDigits(char *MMDDCCYYDate, char *CCDigitsPar) 
{
    char MMDDCCYYBuffer[9];
    static char CCDigits[3]; 
    strcpy (MMDDCCYYBuffer, MMDDCCYYDate);
    memset (CCDigits, '\0', 3);
    CCDigits[0] = MMDDCCYYBuffer[4]; 
    CCDigits[1] = MMDDCCYYBuffer[5]; 
    CCDigits[2] = '\0'; 
    strcpy(CCDigitsPar, CCDigits); 
    return (atoi(CCDigitsPar));
}

////////////////////////////////////////////////////////////////
//  Function:  MWDDYYToMMDDCCYY
//  Description:  Date converter.
//  Returns:  char *--MMDDCCYYDate on Ok, "" if not.
////////////////////////////////////////////////////////////////
char *
MWDDYYToMMDDCCYY(int CCDigits, char *MWDDYYDate,
    char *MMDDCCYYDate)
{
    char MWDDYYDBuffer[7], CCDigitsBuffer[3],
         MonthDigits[3]; 
    static char MMDDCCYYBuffer[9]; 
    _itoa (CCDigits, CCDigitsBuffer, 10);
    strcpy (MWDDYYDBuffer, MWDDYYDate);
    if (isxdigit((int)MWDDYYDBuffer[0])) {
        strcpy(MonthDigits, XDigitToDecimal(MWDDYYDBuffer[0])); 
        strcpy(MMDDCCYYBuffer, MonthDigits); // MM
        strncat(MMDDCCYYBuffer, &MWDDYYDBuffer[2],2);// DD
        MMDDCCYYBuffer[4]='\0';
        strcat(MMDDCCYYBuffer, CCDigitsBuffer);// CC 
        strncat(MMDDCCYYBuffer, &MWDDYYDBuffer[4],2);// YY
        MMDDCCYYBuffer[8]='\0'; 
        strcpy (MMDDCCYYDate, MMDDCCYYBuffer);
        return MMDDCCYYBuffer;
    }
    return ""; // error
}

////////////////////////////////////////////////////////////////
//  Function:  FindDay
//
//  Description: Calculates the day of the week by a given date.
//
//
//  Returns: int day of week (look at enum days).
////////////////////////////////////////////////////////////////
int FindDay(char *MMDDCCYYDate)
{
    int Index, Month, Date, CCDigits, YYDigits,
        FirstTwoMonthsIndex;
    static int Day; 
    char MMDDCCYYBuffer[9];
    strcpy(MMDDCCYYBuffer, MMDDCCYYDate);  
    Month=Get(MMDDCCYYBuffer, (int)MM);
    Date=Get(MMDDCCYYBuffer, (int)DD);
    CCDigits=Get(MMDDCCYYBuffer, (int)CC);
    YYDigits=Get(MMDDCCYYBuffer, (int)YY);
    FirstTwoMonthsIndex=
        (IsGregorianLeapYear(MMDDCCYYBuffer)  && 
         Month<=2)?-1:0;
    Index=(Date+FirstTwoMonthsIndex+
        FindMonthIndex(Month)+YYDigits+YYDigits/4+
        FindCenturyBenchmarkDay(CCDigits))%7;
    Index = (Index >= 0) ? Index : (7 + Index);
    Day = Index;
    return (Day);
}

////////////////////////////////////////////////////////////////
//  Function:  FindCenturyBenchmarkDay
//  Description: Calculates benchmark day for a century.  
//  Returns:  int -- day.  For the Gregorian calendar the last
//  day of the last century is the benchmark.
////////////////////////////////////////////////////////////////
int FindCenturyBenchmarkDay(int CCDigits)
{
    return (SATURDAY-2*(CCDigits%4));
}

/* End of File */