>>/* >>* Program Name: date.c >>* Author: Pat Y. Boens >>* Copyright (c) 1995 by The DVL Group >>* ------------------------------------------------------------------------------ >>* Created: 26 July 1995 at 10:27 >>* >>* .............................................................................. >>* Revision number : 1.0 Last Revised : 26 July 1995 at 10:27 >>* Description : Date functions. >>* .............................................................................. >>* Revision number : 2.0 Last Revised : 21 May 1998 at 23:35 >>* Description : DAT_easter() public domain by Ed Bernal >>* .............................................................................. >>* >>* Part of FOCUS >>* >>* ------------------------------------------------------------------------------ >>*/ >> >>#include <windows.h> >>#include <string.h> >> >>#include "pro_ext.h" >>#include "focus.h" >>#include "date.h" >>#include "D:\FOCUS\5.0\FastWrite\functions.h" >> >>#define NUMBER_OF_SECONDS_PER_DAY 86400 >> >>#ifdef PAPAL // Pope Gregory XIII's decree >>#define LASTJULDATE 15821004L // last day to use Julian calendar >>#define LASTJULJDN 2299160L // jdn of same >>#else // British-American usage >>#define LASTJULDATE 17520902L // last day to use Julian calendar >>#define LASTJULJDN 2361221L // jdn of same >>#endif >> >>long ymd_to_jdnl( int y,int m,int d,int julian ); >>void jdnl_to_ymd( long jdn,int *yy,int *mm,int *dd,int julian ); >>void easter(int year,int *easter_month, int *easter_day ); >> >>void easter(int year,int *easter_month, int *easter_day ) >>/*-----------------------------------------------------*/ >>{ >> int a,b,c,e,g,h,i,k,u,x,z; >> div_t f; >> >> /* >> ** Gauss' famous algorithm (I don't know how or why it works, >> ** so there's no commenting) >> */ >> >> a = year % 19; >> f = div(year,100); >> b = f.quot; >> c = f.rem; >> f = div(b,4); >> z = f.quot; >> e = f.rem; >> f = div((8*b + 13),25); >> g = f.quot; >> f = div((19*a + b - z - g + 15),30); >> h = f.rem; >> f = div((a + 11*h),319); >> u = f.quot; >> f = div(c,4); >> i = f.quot; >> k = f.rem; >> f = div((2*e + 2*i - k - h + u + 32),7); >> x = f.rem; >> f = div((h-u+x+90),25); >> *easter_month = f.quot; >> f = div((h-u+x + *easter_month +19),32); >> *easter_day = f.rem; >>} >> >>long ymd_to_jdnl( int y,int m,int d,int julian ) >>/*--------------------------------------------*/ >>{ >> long jdn; >> >> if ( julian < 0 ) /* set Julian flag if auto set */ >> julian = (((y * 100L) + m) * 100 + d <= LASTJULDATE); >> >> if (y < 0) /* adjust BC year */ >> y++; >> >> if (julian) >> jdn = 367L * y - 7 * (y + 5001L + (m - 9) / 7) / 4 >> + 275 * m / 9 + d + 1729777L; >> else >> jdn = (long)(d - 32076) >> + 1461L * (y + 4800L + (m - 14) / 12) / 4 >> + 367 * (m - 2 - (m - 14) / 12 * 12) / 12 >> - 3 * ((y + 4900L + (m - 14) / 12) / 100) / 4 >> + 1; /* correction by rdg */ >> return jdn; >>} >> >>void jdnl_to_ymd( long jdn,int *yy,int *mm,int *dd,int julian ) >>/*-----------------------------------------------------------*/ >>{ >> long x,z,m,d,y; >> long daysPer400Years = 146097L; >> long fudgedDaysPer4000Years = 1460970L + 31; >> >> if (julian < 0) /* set Julian flag if auto set */ >> julian = (jdn <= LASTJULJDN); >> >> x = jdn + 68569L; >> >> if ( julian ) >> { >> x += 38; >> daysPer400Years = 146100L; >> fudgedDaysPer4000Years = 1461000L + 1; >> } >> >> z = 4 * x / daysPer400Years; >> x = x - (daysPer400Years * z + 3) / 4; >> y = 4000 * (x + 1) / fudgedDaysPer4000Years; >> x = x - 1461 * y / 4 + 31; >> m = 80 * x / 2447; >> d = x - 2447 * m / 80; >> x = m / 11; >> m = m + 2 - 12 * x; >> y = 100 * (z - 49) + y + x; >> *yy = (int)y; >> *mm = (int)m; >> *dd = (int)d; >> if (*yy <= 0) /* adjust BC years */ >> (*yy)--; >>} >> >> >>FOCUSFNC FW_DAT_easter( XBASE_PARAMETERS ) >>/*--------------------------------------*/ >>{ >> int yr,mo,dy; >> >> // Julian date to Year-Month-Day >> jdnl_to_ymd( (long) Parm->p[0].val.ev_real,&yr,&mo,&dy,0 ); >> // Determine Easter day >> easter( yr,&mo,&dy ); >> // Put all this together back as a Julian date >> Parm->p[0].val.ev_real = ymd_to_jdnl( yr,mo,dy,0 ); >> // Return the RetVal structure to return a date to FoxPro >> _RetVal( &Parm->p[0].val ); >> FOCUSFNCRETURN(); >>} >> >>FOCUSFNC FW_DAT_ymd( XBASE_PARAMETERS ) >>/*-----------------------------------*/ >>{ >> int yr, mo, dy; >> Value val1,val2,val3; >> >> _Load( &Parm->p[1].loc,&val1 ); // Put loc in val >> _Load( &Parm->p[2].loc,&val2 ); // Put loc in val >> _Load( &Parm->p[3].loc,&val3 ); // Put loc in val >> >> jdnl_to_ymd( (long) Parm->p[0].val.ev_real,&yr,&mo,&dy,0 ); // Julian date to Year-Month-Day >> >> val1.ev_real = yr; >> val2.ev_real = mo; >> val3.ev_real = dy; >> >> _Store( &Parm->p[1].loc,&val1 ); >> _Store( &Parm->p[2].loc,&val2 ); >> _Store( &Parm->p[3].loc,&val3 ); >> >> FOCUSFNCRETURN(); >>} >> >>FOCUSFNC FW_DAT_year( XBASE_PARAMETERS ) >>/*------------------------------------*/ >>{ >> int yr, mo, dy; >> >> jdnl_to_ymd( (long) Parm->p[0].val.ev_real,&yr,&mo,&dy,0 ); // Julian date to Year-Month-Day >> >> _retni( yr ); >> >> FOCUSFNCRETURN(); >>} >> >>FOCUSFNC FW_DAT_month( XBASE_PARAMETERS ) >>/*------------------------------------*/ >>{ >> int yr, mo, dy; >> >> jdnl_to_ymd( (long) Parm->p[0].val.ev_real,&yr,&mo,&dy,0 ); // Julian date to Year-Month-Day >> >> _retni( mo ); >> >> FOCUSFNCRETURN(); >>} >> >>FOCUSFNC FW_DAT_day( XBASE_PARAMETERS ) >>/*------------------------------------*/ >>{ >> int yr, mo, dy; >> >> jdnl_to_ymd( (long) Parm->p[0].val.ev_real,&yr,&mo,&dy,0 ); // Julian date to Year-Month-Day >> >> _retni( dy ); >> >> FOCUSFNCRETURN(); >>} >> >>FOCUSFNC FW_DAT_num( XBASE_PARAMETERS ) >>/*-----------------------------------*/ >>{ >> /* Documented */ >> _retnd( _pard(1) ); // This is in fact returning the julian date !!! >> FOCUSFNCRETURN(); >>} >> >>FOCUSFNC FW_DAT_boy( XBASE_PARAMETERS ) >>/*-----------------------------------*/ >>{ >> int yr, mo, dy; >> long jdn; >> >> jdnl_to_ymd( (long) Parm->p[0].val.ev_real,&yr,&mo,&dy,0 ); // Julian date to Year-Month-Day >> mo = 1; >> dy = 1; >> >> jdn = ymd_to_jdnl( yr,mo,dy,0 ); // Year-Month-Day to Julian date >> >> Parm->p[0].val.ev_real = jdn; >> _RetVal( &Parm->p[0].val ); >> >> FOCUSFNCRETURN(); >>} >> >>FOCUSFNC FW_DAT_bom( XBASE_PARAMETERS ) >>/*-----------------------------------*/ >>{ >> int yr, mo, dy; >> long jdn; >> >> jdnl_to_ymd( (long) Parm->p[0].val.ev_real,&yr,&mo,&dy,0 ); // Julian date to Year-Month-Day >> dy = 1; >> >> jdn = ymd_to_jdnl( yr,mo,dy,0 ); // Year-Month-Day to Julian date >> >> Parm->p[0].val.ev_real = jdn; >> _RetVal( &Parm->p[0].val ); >> >> FOCUSFNCRETURN(); >>} >> >>FOCUSFNC FW_DAT_eoy( XBASE_PARAMETERS ) >>/*-----------------------------------*/ >>{ >> int yr, mo, dy; >> long jdn; >> >> jdnl_to_ymd( (long) Parm->p[0].val.ev_real,&yr,&mo,&dy,0 ); // Julian date to Year-Month-Day >> mo = 12; >> dy = 31; >> >> jdn = ymd_to_jdnl( yr,mo,dy,0 ); // Year-Month-Day to Julian date >> >> Parm->p[0].val.ev_real = jdn; >> _RetVal( &Parm->p[0].val ); >> >> FOCUSFNCRETURN(); >>} >> >>BOOL isleap( long jdn ) >>/*-------------------*/ >>{ >> int yr, mo, dy; >> long jdn1,jdn2; >> >> jdnl_to_ymd( jdn,&yr,&mo,&dy,0 ); // Julian date to Year-Month-Day >> jdn1 = ymd_to_jdnl( yr,1,1,0 ); // Year-Month-Day to Julian date >> jdn2 = ymd_to_jdnl( yr,12,31,0 ); // Year-Month-Day to Julian date >> >> return (( jdn2 - jdn1 ) == 365 ); // A difference of 365 indicates 366 days !!! >>} >> >>FOCUSFNC FW_DAT_isleap( XBASE_PARAMETERS ) >>/*--------------------------------------*/ >>{ >> _retl( isleap( (long) Parm->p[0].val.ev_real ) ); >> FOCUSFNCRETURN(); >>} >> >>FOCUSFNC FW_DAT_eom( XBASE_PARAMETERS ) >>/*-----------------------------------*/ >>{ >> int yr, mo, dy; >> long jdn; >> enum months { january,february,march,april,may,june,july,august,september,october,november,december }; >> >> jdnl_to_ymd( (long) Parm->p[0].val.ev_real,&yr,&mo,&dy,0 ); // Julian date to Year-Month-Day >> >> switch ( mo - 1 ) >> { >> case january : dy = 31; break; >> case february : if ( isleap( (long) Parm->p[0].val.ev_real ) ) >> dy = 29; >> else >> dy = 28; >> break; >> case march : dy = 31; break; >> case april : dy = 30; break; >> case may : dy = 31; break; >> case june : dy = 30; break; >> case july : dy = 31; break; >> case august : dy = 31; break; >> case september : dy = 30; break; >> case october : dy = 31; break; >> case november : dy = 30; break; >> case december : dy = 31; >> } >> >> jdn = ymd_to_jdnl( yr,mo,dy,0 ); // Year-Month-Day to Julian date >> >> Parm->p[0].val.ev_real = jdn; >> _RetVal( &Parm->p[0].val ); >> >> FOCUSFNCRETURN(); >>} >> >>FOCUSFNC FW_DAT_NumberOfDays( XBASE_PARAMETERS ) >>/*--------------------------------------------*/ >>{ >> /* Documented */ >> short n; >> enum months { january,february,march,april,may,june,july,august,september,october,november,december }; >> >> switch ( _parni(1) - 1 ) >> { >> case january : n = 31; break; >> case february : n = 28; break; >> case march : n = 31; break; >> case april : n = 30; break; >> case may : n = 31; break; >> case june : n = 30; break; >> case july : n = 31; break; >> case august : n = 31; break; >> case september : n = 30; break; >> case october : n = 31; break; >> case november : n = 30; break; >> case december : n = 31; break; >> default : n = 0; >> } >> >> _retni( n ); >> FOCUSFNCRETURN(); >>} >> >>FOCUSFNC FW_DAT_DateTime( XBASE_PARAMETERS ) >>/*----------------------------------------*/ >>{ >> TCHAR buffer[21]; >> >> DateTime( buffer ); >> _retc( buffer ); >> >> FOCUSFNCRETURN(); >>} >>