home *** CD-ROM | disk | FTP | other *** search
- /* This function module provides three functions for manipulating dates:
- /* LegalDays -- adjusts dates to reflect actual number of days per month
- /* FromDosDate -- converts information provided via AmigaDos DateStamp to
- /* MM, DD, YYYY, Hour, Minute, Second information
- /* ToDosDate -- converts MM, DD, YYYY, Hour, Minute and Second data to
- /* AmigaDos DateStamp format */
-
- /* First we need to get various structure and DEFINE info... */
- #include <libraries/dos.h>
- #include <lattice/stdio.h>
-
- /* Right now, AmigaDos' day zero is midnight, 1 January 1978 */
- #define STARTYEAR 1978
-
- /* This keeps the compiler happy; DateStamp() is an AmigaDos function */
- void DateStamp();
-
- /* This function takes three arguments and returns a 'legal' day number,
- /* defined as follows:
- /* - the supplied day number if it is legitimate (e.g., March 31, or
- /* Feb 29 in a leap year)
- /* - the last legitimate day of the specified month (e.g., Feb 28 if Feb 29
- /* is supplied and Year is not a leap year
- /* - 1 if the supplied day number is less than or equal to zero
- /* January is month number 1. */
-
- int LegalDays(Month,Day,Year)
- int Month,Day,Year;
- {
- /* First make sure we have a positive date */
- Day=Day<=0?1:Day;
- /* What we do depends on what month we're in */
- switch(Month)
- {
- /* February...*/
- case 2:
- /* Leap years. Years divisible by 400, e.g., 2000, are not leap years */
- if(Year%4==0 && Year%400!=0)
- {
- if(Day>29)
- Day=29;
- }
- /* Normal years */
- else
- {
- if(Day>28)
- Day=28;
- }
- break;
- /* Months with 30 days */
- case 4:
- case 6:
- case 9:
- case 11:
- if(Day>30)
- Day=30;
- break;
- /* Months with 31 days, which is everything else */
- default:
- if(Day>31)
- Day=31;
- break;
- }
- return(Day);
- }
-
- /* This function 'returns' pointers to integers specifying month, day, year,
- /* hour, minute and second as known by AmigaDos. 'Returns' is in quotes
- /* because we are doing call by reference (I think) here to get around
- /* C's limitation on only returning one value from a function.*/
-
- void FromDosDate(DosPtr,MPtr,DPtr,YPtr,HPtr,MinPtr,SPtr)
- struct DateStamp *DosPtr;
- int *MPtr,*DPtr,*YPtr,*HPtr,*MinPtr,*SPtr;
- {
- int NumLeap,NumReg;
-
- /* Number of leap years between 1978 and current date. Dos returns the
- /* number of days between 1/1/1978 and current date. What we do here is
- /* calculate the number of 1461 day periods (4 years, including the leap)
- /* since 1/1/1978. We need to adjust for the fact that the first leap
- /* after 1/1/1978 was only two years later, in 1980.*/
-
- NumLeap=(DosPtr->ds_Days+((STARTYEAR-1)%4)*365)/1461;
-
- /* The number of regular years is the number of days left after we subtract
- /* 366 days for each leap year divided by 365 days */
-
- NumReg=(DosPtr->ds_Days-366*NumLeap)/365;
-
- /* If we've calculated a year beyond 2000 we need to adjust for the fact
- /* that the year 2000 is not a leap year.*/
- *YPtr=STARTYEAR+NumLeap+NumReg;
- if(*YPtr>2000)
- {
- --NumLeap;
- NumReg=(DosPtr->ds_Days-366*NumLeap)/365;
- *YPtr=STARTYEAR+NumLeap+NumReg;
- }
-
- /* Now we'll subtract out the number of days in each month of the year
- /* until we go nonpositive, at which point we'll have reached the correct
- /* month. To start, we need to reduce the day count by the number of days
- /* in the years between 1/1/1978 and current time and reset the month
- /* counter.*/
-
- *DPtr=DosPtr->ds_Days-366*NumLeap-365*NumReg+1;
- *MPtr=0;
- while(*DPtr>0)
- {
- *DPtr-=LegalDays(*MPtr,99,*YPtr);
- ++*MPtr;
- }
-
- /* Actually, we've skipped to the end of the correct month, so add back
- /* its number of days.*/
-
- *DPtr+=LegalDays(*MPtr-1,99,*YPtr);
-
- /* Now do seconds, minutes and hours. */
- *SPtr=DosPtr->ds_Tick/TICKS_PER_SECOND;
- *HPtr=DosPtr->ds_Minute/60;
- *MinPtr=DosPtr->ds_Minute-*HPtr*60;
- }
-
- /* This function 'returns' a pointer to a DateStamp structure which is
- /* initialized according to user-supplied date and time information. The
- /* returned pointer could have been returned by value, rather than by
- /* reference, but I wanted to keep the parameter list identical to
- /* FromDosDate().*/
-
- void ToDosDate(DosPtr,MPtr,DPtr,YPtr,HPtr,MinPtr,SPtr)
- struct DateStamp *DosPtr;
- int *MPtr,*DPtr,*YPtr,*HPtr,*MinPtr,*SPtr;
- {
- int NumLeap,Month=0;
-
- /* The number of leap years since 1/1/1978 is modulo 4 the number of years
- /* between the current date and 1978. However, we must adjust for the fact
- /* that the first leap year after 1978 was only two years later in 1980.*/
-
- NumLeap=(*YPtr-STARTYEAR+(STARTYEAR-1)%4)/4;
-
- /* Once again, we adjust for 2000 not being a leap year */
-
- if(*YPtr>2000)
- --NumLeap;
-
- /* The number of days since 1978 is, to begin with, 366 for every leap
- /* year since then and 365 for every other year since then. */
-
- DosPtr->ds_Days=NumLeap*366+(*YPtr-STARTYEAR-NumLeap)*365;
-
- /* Now we add in the days for each month up to the month before the
- /* current one.*/
-
- while(Month<(*MPtr-1))
- {
- DosPtr->ds_Days+=LegalDays(Month,99,*YPtr);
- ++Month;
- }
-
- /* Now add the day number within the current month. We must subtract 1
- /* because AmigaDos treats 1/1/1978 as 0 days away from its time zero.*/
- DosPtr->ds_Days+=*DPtr-1;
-
- /* Convert seconds to ticks */
- DosPtr->ds_Tick=*SPtr*TICKS_PER_SECOND;
- /* Convert hours and minutes to minutes since midnight */
- DosPtr->ds_Minute=*HPtr*60+*MinPtr;
- }
-