Files correlati : Ricompilazione Demo : [ ] Commento : Aggiunti i sorgenti per Greenleaf Math Library (gfm.dll) git-svn-id: svn://10.65.10.50/trunk@10079 c028cbd2-c16b-5b4b-a496-9718f37d4682
144 lines
4.1 KiB
C
Executable File
144 lines
4.1 KiB
C
Executable File
/* int DaysBetweenDates365(m1,d1,y1, m2,d2,y2)
|
|
*
|
|
* ARGUMENT
|
|
* int m1,d1,y1; - Base Date
|
|
* int m2,d2,y2; - Date to compare with base
|
|
*
|
|
* DESCRIPTION
|
|
* Compares two dates in date args format, forming the difference in
|
|
* whole days. The result is a signed number:
|
|
*
|
|
* 0 if dates are same,
|
|
* +n if date1 > date2
|
|
* -n if date1 < date2
|
|
*
|
|
* SIDE EFFECTS
|
|
* None.
|
|
*
|
|
* RETURNS
|
|
* +,-, or 0 days. 0 can indicate an error.
|
|
*
|
|
* POSSIBLE ERROR CODES
|
|
* GM_ARGVAL
|
|
* GM_OVERFLOW
|
|
*
|
|
* AUTHOR
|
|
* 05-Aug-1987 12:43:39
|
|
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
|
|
*
|
|
* MODIFICATIONS
|
|
*
|
|
* 01-Jan-1989 Corrected for true Gregorian Calendar
|
|
*
|
|
* DISCUSSION
|
|
*
|
|
* It may not be entirely clear when reading this code just what is going
|
|
* on. First of all, the calendar used is the Greenleaf version of the
|
|
* Gregorian calendar. We assume in this calendar that Gregorian time
|
|
* extends backwards to the year 0, and forward forever, more or less.
|
|
* A leap year occurs every four years. Except when the year is evenly
|
|
* divisible by 100, like the year 1900, when there is no leap year. Except
|
|
* when the year is evenly divisible by 400, in which case there really
|
|
* is a leap year.
|
|
*
|
|
* The way this algorithm works is relatively simple. There are four
|
|
* mysterious variables in this program: n1, n2, x and z. n1 and n2 are
|
|
* relatively easy to understand. These variables are simple the number
|
|
* of days since January 1, year 0. The difference between these two numbers
|
|
* is the actual number returned by this function.
|
|
*
|
|
* In order to calculate the number of days since 1/1/0, we can start by
|
|
* adding 365 days per year:
|
|
*
|
|
* n = 365 * y
|
|
*
|
|
* This gets a pretty good rough number, but it doesn't take into account
|
|
* the leap years. Given the Greenleaf Gregorian calendar, we can add in
|
|
* all the days accounted for by leap years like this:
|
|
*
|
|
* n = 365 * y + y/4 - y/100 + y/400
|
|
*
|
|
* This works pretty well, but it leaves us with one problem: we are
|
|
* adding in a leap day in leap years, even if the month is January
|
|
* or February. On January 1, 1984, we haven't hit the leap day yet, so
|
|
* we shouldn't add it in. This is where z comes from. y is the actual
|
|
* year, but z is the year used for calculation of leap days:
|
|
*
|
|
* if ( m <= 2 )
|
|
* z = y - 1;
|
|
* else
|
|
* z = y;
|
|
* n = 365 * y + y/4 - y/100 + y/400
|
|
*
|
|
* At this point, n is accurate for January 1 of the given year. Now we
|
|
* have to add in the days accounted for by the months in the selected year.
|
|
* A good guess on how to do this is to just add 31 days per month:
|
|
*
|
|
* n = 365 * y + y/4 - y/100 + y/400 + 31*(m - 1)
|
|
*
|
|
* The only problem is that starting with month 3, there will be errors
|
|
* in the calculation. The good news is that a simple formula will generate
|
|
* a correction factor, which is x. The formula for x is (4*m + 23) / 10.
|
|
* This just happens to generate the correct sequence of numbers. A different
|
|
* way would be to create an x array {0, 0, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7};
|
|
* So now my formula looks like this:
|
|
*
|
|
* if ( m <= 2 ) {
|
|
* x = 0;
|
|
* z = y - 1;
|
|
* } else {
|
|
* z = y;
|
|
* x = ( 4 * m + 23 ) / 10 ;
|
|
* }
|
|
* n = 365 * y + y/4 - y/100 + y/400 + 31*(m - 1)
|
|
*
|
|
* The final step is to add in the day of the month, to account for all the
|
|
* days in the current month. Do that and you are done.
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include "gmsystem.h"
|
|
|
|
int DaysBetweenDates365(m1,d1,y1,m2,d2,y2)
|
|
int m1,d1,y1,m2,d2,y2;
|
|
{
|
|
long n1, n2, n;
|
|
int x, z;
|
|
|
|
_MacStart(GM_DBD365);
|
|
|
|
if (m1<1||m1>12||d1<1||d1>31||y1<0||y1>9999||
|
|
m2<1||m2>12||d2<1||d2>31||y2<0||y2>9999) {
|
|
_MacErr(GM_ARGVAL);
|
|
_MacRet(GM_ARGVAL);
|
|
}
|
|
|
|
if (m1<=2) {
|
|
x=0;
|
|
z=y1-1;
|
|
} else {
|
|
x=(4*m1 + 23) / 10;
|
|
z=y1;
|
|
}
|
|
n1 = (long) y1 * 365L + (long) (31*(m1-1) + d1 + z/4 - z/100 + z/400 - x);
|
|
|
|
if (m2<=2) {
|
|
x=0;
|
|
z=y2-1;
|
|
} else {
|
|
x=(4*m2 + 23) / 10;
|
|
z=y2;
|
|
}
|
|
n2 = (long) y2 * 365L + (long) (31*(m2-1) + d2 + z/4 - z/100 + z/400 - x);
|
|
|
|
n = n1 - n2;
|
|
|
|
if (n<-32768L||n>32767L) {
|
|
_MacErr(GM_OVERFLOW);
|
|
_MacRet(GM_OVERFLOW);
|
|
}
|
|
|
|
_MacRet((int) n);
|
|
}
|