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);
 | 
						|
}
 |