Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Leap years
Message
Information générale
Forum:
Visual FoxPro
Catégorie:
Codage, syntaxe et commandes
Titre:
Divers
Thread ID:
00115008
Message ID:
00115192
Vues:
22
Leap years ?

This is the code I can think of when it comes down to leap years. I have extracted all the code from FOCUS.FLL so that you'll find functions that have nothing to do with leap years. As far as the rules are concerned, you'll find them all. Ready ?
/*
* 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();
}
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform