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