home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
007.lha
/
settime
/
date.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-11-10
|
6KB
|
172 lines
/* 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;
}