home *** CD-ROM | disk | FTP | other *** search
- /* DATE.C - Mark Jones' date/calendar routines for Windows 3.0
-
- Copyright (c) 1990, 1991, Mark Jones
- 713 Lisa Ln.
- Cedar Hill, TX 75104
- (214) 291-0509
- Compuserve 70511,706
- */
-
- #define _WINDOWS
- #define _WINDLL
-
- #include <windows.h>
- #include "Date.h"
-
- #include <float.h>
- #include <math.h>
-
- /*****************************************************************************
-
- MODIFICATION LOG
-
- Date Version Who Change
- ---- ------- --- --------------------------------------------------
- 3 OCT 90 1.00 Mark J. Added DATE.ICO as a resource
- Finished DateObj() and tested
- 22 OCT 1.01 Mark J. Add _WINDOWS and _WINDLL and recompiled with
- warning level 3 (W3), fixing certain conversion
- warnings
- 2/10/91 Changed "<win.h>" reference to <windows.h>
-
-
- *****************************************************************************/
- /*****************************************************************************/
-
- /* MISC. DEFINITIONS */
-
- #define SET_ERR(ErrCode) ( ((((LONG) DATE_ERROR)<<16)&0xFFFF0000L) + ErrCode)
-
-
- /*****************************************************************************/
-
- /* GLOBAL FIELDS */
-
- int MoDaTbl[12] = { /* days-in-month table */
- 31, 29, 31, 30, 31, 30,
- 31, 31, 30, 31, 30, 31 };
-
-
-
- /*****************************************************************************/
- /*****************************************************************************/
-
- /* OBJECT-ORIENTED DATE.DLL FUNCTIONS */
-
- /*****************************************************************************/
- /*****************************************************************************/
-
- /* DateObj() : INTERFACE WITH DATE.DLL AS A SINGLE OBJECT */
-
- /* This function allows external access to the functionality of DATE.DLL via
- a generic "object" interface. "DateObj" is the name of the object, and this
- function presents "DateObj" in a way that resembles the interface to a
- true object. Such an interface may be desirable in table-driven
- applications, or in systems that recognize only primitive data types,
- and have no ability to inspect a data structure. DateObj() is also
- applicable to third-party software tools that cannot efficiently access
- data-structure elements, such as Toolbook and Plus, or simply in situations
- where a simpler, object-oriented interface is desired.
-
- ----------
- PROTOTYPE:
- ----------
-
- LONG FAR PASCAL DateObj(HANDLE hDateObj, WORD uMsg, WORD uID, LONG lParam)
-
- ------
- INPUT:
- ------
- The following input parameters are used in the interface with "DateObj" :
-
- Parameter Possible values Meaning/Usage
- --------- --------------- ----------------------------------------------
- HANDLE hDateObj This is the handle to an instance of the
- "DateObj" object. Each object-instance will
- be created by the CREATE message.
-
- WORD uMsg CREATE Creates a new "DateObj" object - used only
- when the ID value is DATE
- DELETE Deletes an existing "DateObj" object - used
- only when the ID value is DATE
- SET Used to set a property or value in DateObj,
- or to initialize the entire DateObj to NULLs
- GET Retrieves a propery or value from DateObj
- CALCULATE Forces DateObj to recalculate itself, based
- on either a julian or a normal date; the
- calculation method is determined by setting
- lParam to either JULIAN or NORMAL. When
- CALCULATE is used, the value of uID doesn't
- matter.
-
- WORD uID DATE A "DateObj" object - used only with CREATE,
- DELETE, and SET messages
- MONTH Month number, from 1 to 12
- DAY Day of month, from 1 to 31
- YEAR Year, from 1901 to 2100
- JULIANDATE Julian date value, from 1 to 72743
- LEAPYEAR Does this date fall within a leap year?
- DAYOFWEEK What is the day of the week (0 to 6)?
- DAYOFYEAR What is the day of the year (1 to 366)?
- DAYSINMONTH How many days are in the month (1 to 31)?
-
- LONG lParam * The lParam parameter is used only when the
- uMsg has a value of SET. lParam should
- contain the numeric value associated with
- the uID during a SET operation. The following
- values are valid lParam values:
-
- uID valid lParam value(s)
- --- ----------------------
- DATE 0
- MONTH 1 to 12
- DAY 1 to 31
- YEAR 1 to 2100
- JULIANDATE 1 to 72743
- LEAPYEAR N/A (does not use SET)
- DAYOFWEEK N/A (does not use SET)
- DAYOFYEAR N/A (does not use SET)
-
- -------
- OUTPUT:
- -------
- The "DateObj" function returns a LONG value which varies depending on the
- input-message and the ID. If an error occurred, the HIWORD of the
- LONG return value will contain the value DATE_ERROR, and the LOWORD
- will contain a mnemonic code explaining the cause of the error. The
- following table summarizes the meanings of the possible error values
- in LOWORD:
-
- LOWORD error value Meaning
- ------------------ ----------------------------------------------
- GENERAL_FAILURE The operation cannot be performed because of
- an underlying system failure, such as a lack
- of memory, etc.
- BAD_INPUT A bad lParam value was passed to DateObj().
- NULL_HANDLE The hDateObj value had a NULL (0) value.
- BAD_HANDLE The hDateObj value was non-NULL, but it was not
- usable by DateObj().
- BAD_ID The uID value was not valid. See the "INPUT"
- section above for a list of valid uID values.
- WRONG_ID The uID value was valid, but was not usable
- in the context of the call. For example, since
- a CREATE message applies only to a DATE object,
- the following would produce an error:
-
- lResult =
- DateObj(hDateObj, CREATE, MONTH, lParam);
-
- but the following would be valid:
-
- lResult =
- DateObj(hDateObj, CREATE, DATE, lParam);
-
- BAD_MESSAGE An invalid value was passed on the uMsg parameter.
- Consult the "INPUT" section above for a list of
- valid uMsg values.
- FATAL_ERROR An unexplainable error occurred during a CALCULATE
- operation, and DateObj couldn't complete its
- processing. This error points to a bug in DATE.DLL!
-
- More specific information is provided below explaining the possible error-
- return values.
-
- If the HIWORD of the LONG return value is not equal to DATE_ERROR, the
- LOWORD value represents the result of a normal procedure.
-
- The way to test for success after returning from a DateObj() call is with
- statements similar to:
-
- lResult = DateObj(hDateObj, uMsg, uId, lParam);
- if (HIWORD(lResult) != DATE_ERROR)
- nResultNormal = LOWORD(lResult);
- else
- myErrorHandler(LOWORD(lResult));
-
- The following table details the possible DateObj() return values.
-
- -----------------------------
- DateObj() return-values table
- -----------------------------
-
- uMsg DateObj LONG return value
- ---- ----------------------------------------------------------------
- CREATE HIWORD = DATE_ERROR: A Date object could not be created
- LOWORD = GENERAL_FAILURE:
- Memory could not be alloc'd
- WRONG_ID: A uID != DATE was passed
- -*-
- HIWORD = 0: The instance of DateObj was created
- LOWORD = A valid handle to the DateObj object
-
- DELETE HIWORD = DATE_ERROR: The Date object could not be
- deleted
- LOWORD = WRONG_ID: A uID != DATE was passed, or
- the hDateObj parameter was NULL
- NULL_HANDLE:A value of NULL (0) was passed in hDateObj
- GENERAL_FAILURE:
- DateObj memory cannot be freed! The
- hDateObj value might be garbage.
- -*-
- HIWORD = 0: The instance of DateObj was destroyed.
- LOWORD = hDateObj (this handle is now meaningless)
-
- SET HIWORD = DATE_ERROR: The element could not be set
- LOWORD = BAD_INPUT: A bad value was passed, which fell outside
- the allowed range.
- NULL_HANDLE:The hDateObj handle was NULL (0).
- BAD_HANDLE: The hDateObj handle parameter was garbage.
- -*-
- HIWORD = 0: The item was initialized. If uID == DATE, then
- the DateObj was set to all NULLs (0s).
- LOWORD = hDateObj
-
- GET HIWORD = DATE_ERROR: The element could not be retrieved
- LOWORD = NULL_HANDLE:The hDateObj handle was NULL (0).
- GENERAL_FAILURE:
- The DateObj could not be found. The
- hDateObj handle might be garbage!
- BAD_ID: The uID value was not recognized. See
- the "INPUT" section above for a list
- of the valid values for uID.
- -*-
- HIWORD = 0: The element's value was successfully retrieved.
- LOWORD = Element value (except with YEAR, in which it is likely
- that a portion of the HIWORD could be used; in any case,
- the HIWORD will never == DATE_ERROR on a normal return)
-
- CALCULATE
- HIWORD = DATE_ERROR: DateObj could not calculate itself
- LOWORD = NULL_HANDLE:The hDateObj handle was NULL (0).
- GENERAL_FAILURE:
- The DateObj could not be found. The
- hDateObj handle might be garbage!
- BAD_INPUT: The values in DateObj from which the
- calculations are made are bad -- you
- screwed up by passing a wrong value
- during a SET message.
- FATAL_ERROR:A bug exists in DATE.DLL! Scream
- vigorously at Mark Jones.
-
- <other> HIWORD = DATE_ERROR: An invalid uMsg value was used
- LOWORD = BAD_MESSAGE: "
- */
-
- /*****************************************************************************/
-
- LONG FAR PASCAL DateObj(HANDLE hDateObj, WORD uMsg, WORD uID, LONG lParam)
- {
- LONG lReturn; // return() value
- Date FAR *fpDate; // &DateObj
-
- // INITIALIZE RETURN VALUE TO NO-ERROR
- lReturn = 0;
-
- // MAIN OBJECT-MESSAGE (uMsg) DISPATCH switch:
- switch(uMsg)
- {
- //******************************************************************
- case CREATE: // CREATE A NEW DateObj
- if (uID != DATE)
- {
- lReturn = SET_ERR(WRONG_ID);
- break;
- }
- lReturn = (LONG) GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
- sizeof(Date));
- if (!lReturn)
- {
- lReturn = SET_ERR(GENERAL_FAILURE);
- break;
- }
- break; // end of uMsg case CREATE
-
- //******************************************************************
- case DELETE: // DELETE AN EXISTING DateObj
- if (uID != DATE) // If ID doesn't belong here,
- {
- lReturn = SET_ERR(WRONG_ID); // return a WRONG_ID
- break;
- }
- if (!hDateObj) // If NULL hDateObj
- {
- lReturn = SET_ERR(NULL_HANDLE); // return a BAD_INPUT
- break;
- }
- lReturn = hDateObj; // Set lReturn to != DATE_ERROR
- if (GlobalFree(hDateObj)) // If block cannot be freed,
- lReturn = SET_ERR(GENERAL_FAILURE); // return a GENERAL_FAILURE
-
- break; // end of uMsg case DELETE
-
- //******************************************************************
- case SET: // SET A PROPERTY OR VALUE
-
- if (!hDateObj) // If bad hDateObj handle,
- {
- lReturn = SET_ERR(NULL_HANDLE); // return a DATE_ERROR
- break;
- }
- // Get a far pointer to DateObj
- lReturn = (LONG) GlobalLock(hDateObj);
- if (!lReturn) // If unsuccessful,
- {
- lReturn = SET_ERR(BAD_HANDLE); // return a BAD_HANDLE
- break;
- }
- fpDate = (Date FAR *) lReturn; // store &DateObj in fpDate
- lReturn = hDateObj; // successful so far
-
- switch(uID) // Route message
- {
- //----------------------------------------------------------
- case DATE: // SETting a DATE
- fpDate->nYear = // set DateObj to all 0's
- fpDate->nMonth =
- fpDate->nDay =
- fpDate->nLeapYear =
- fpDate->nError =
- fpDate->nYearDays =
- fpDate->nDayOfWeek = 0;
- fpDate->lJulianDate = 0L;
- break;
-
- //----------------------------------------------------------
- case MONTH: // SETting a MONTH
- if (lParam < 1 || lParam > 12) // If outside valid range,
- lReturn = SET_ERR(BAD_INPUT); // return BAD_INPUT
- else // else,
- // set nMonth to lParam
- fpDate->nMonth = LOWORD(lParam);
- break;
-
- //----------------------------------------------------------
- case DAY: // SETting a DAY
- if (lParam < 1 || lParam > 31) // If outside valid range,
- lReturn = SET_ERR(BAD_INPUT); // return BAD_INPUT
- else // else,
- fpDate->nDay = LOWORD(lParam);// set nDay to lParam
- break;
-
- //----------------------------------------------------------
- case YEAR: // SETting a YEAR
- // If outside valid range,
- if (lParam < BASE_YEAR || lParam > CEIL_YEAR)
- lReturn = SET_ERR(BAD_INPUT); // return BAD_INPUT
- else // else,
- // set nYear to lParam
- fpDate->nYear = LOWORD(lParam);
- break;
-
- //----------------------------------------------------------
- case JULIANDATE: // SETting a JULIANDATE
- // If outside valid range,
- if (lParam < 1 || lParam > MAX_JULIAN)
- lReturn = SET_ERR(BAD_INPUT); // return BAD_INPUT
- else // else,
- fpDate->lJulianDate = lParam; // set lJulianDate to lParam
- break;
-
- //----------------------------------------------------------
- default: // bad uID!
- lReturn = SET_ERR(BAD_ID);
- } // end of switch(uID)
-
- GlobalUnlock(hDateObj); // Release fpDate
-
- break; // end of uMsg case SET
-
- //******************************************************************
- case GET: // GET A PROPERTY OR VALUE
-
- if (!hDateObj) // If bad hDateObj handle,
- {
- lReturn = SET_ERR(NULL_HANDLE); // return an DATE_ERROR
- break;
- }
- // Get a far pointer to DateObj
- lReturn = (LONG) GlobalLock(hDateObj);
- if (!lReturn) // If unsuccessful,
- {
- lReturn = SET_ERR(GENERAL_FAILURE); // return a GENERAL_FAILURE
- break;
- }
-
- fpDate = (Date FAR *) lReturn; // store &DateObj in fpDate
- lReturn = hDateObj; // successful so far
-
- switch(uID) // Route message
- {
- //----------------------------------------------------------
- case MONTH: // GETting a MONTH
- lReturn = fpDate->nMonth;
- break;
-
- //----------------------------------------------------------
- case DAY: // GETting a DAY
- lReturn = fpDate->nDay;
- break;
-
- //----------------------------------------------------------
- case YEAR: // GETting a YEAR
- lReturn = fpDate->nYear;
- break;
-
- //----------------------------------------------------------
- case JULIANDATE: // GETting a JULIANDATE
- lReturn = fpDate->lJulianDate;
- break;
-
- //----------------------------------------------------------
- case LEAPYEAR: // GETting a LEAPYEAR
- lReturn = fpDate->nLeapYear;
- break;
-
- //----------------------------------------------------------
- case DAYOFWEEK: // GETting a DAYOFWEEK
- lReturn = fpDate->nDayOfWeek;
- break;
-
- //----------------------------------------------------------
- case DAYOFYEAR: // GETting a DAYOFYEAR
- lReturn = fpDate->nYearDays;
- break;
-
- //----------------------------------------------------------
- case DAYSINMONTH: // GETting a DAYSINMONTH
- lReturn = MoDaTbl[fpDate->nMonth-1];
- if (fpDate->nMonth==2 && !fpDate->nLeapYear)
- lReturn--;
- break;
-
- //----------------------------------------------------------
- default: // bad uID!
- lReturn = SET_ERR(BAD_ID); // return a BAD_ID
-
- } // end of switch(uID)
-
- GlobalUnlock(hDateObj); // Release fpDate
-
- break; // end of uMsg case GET
-
- //******************************************************************
- case CALCULATE: // FORCE DateObj to recalc
-
- if (!hDateObj) // If bad hDateObj handle,
- {
- lReturn = SET_ERR(NULL_HANDLE); // return an DATE_ERROR
- break;
- }
- // Get a far pointer to DateObj
- lReturn = (LONG) GlobalLock(hDateObj);
- if (!lReturn) // If unsuccessful,
- {
- lReturn = SET_ERR(GENERAL_FAILURE); // return a GENERAL_FAILURE
- break;
- }
-
- fpDate = (Date FAR *) lReturn; // store &DateObj in fpDate
- lReturn = hDateObj; // successful so far
-
- switch(lParam) // Route message
- {
- //----------------------------------------------------------
- case JULIAN: // Calc based on julian date
- if (fpDate->lJulianDate < 1 || fpDate->lJulianDate > MAX_JULIAN)
- { // If original julian date was bad,
- // return a BAD_INPUT
- lReturn = SET_ERR(BAD_INPUT);
- break;
- }
- CalcNormalDate(fpDate); // Calculate a normal date
- if (fpDate->nError) // If an error occurred,
- { // report a bug in DATE.DLL and exit!
- lReturn = SET_ERR(FATAL_ERROR);
- break;
- }
- break;
-
- //----------------------------------------------------------
- case NORMAL: // Calc based on normal date
- CheckValidDate(fpDate); // Check for a valid MMDDYYYY date
- if (fpDate->nError) // If an error occurred,
- { // return a BAD_INPUT
- lReturn = SET_ERR(BAD_INPUT);
- break;
- }
- CalcDayOfWeek(fpDate); // Calculate all items
- if (fpDate->nError) // If an error occurred,
- { // report a bug in DATE.DLL and exit!
- lReturn = SET_ERR(FATAL_ERROR);
- break;
- }
- break;
-
- //----------------------------------------------------------
- default: // bad uID!
- lReturn = SET_ERR(BAD_ID); // return a BAD_ID
-
- } // end of switch(uID)
-
- GlobalUnlock(hDateObj); // Release fpDate
-
- break; // end of uMsg case CALCULATE
-
- //******************************************************************
- default: // BAD uMsg value!
- lReturn = SET_ERR(BAD_MESSAGE);
- } // end of switch(uMsg)
-
- return(lReturn); // return LONG value
- }
-
-
- /*****************************************************************************/
- /*****************************************************************************/
-
- /* PROCEDURE-ORIENTED DATE.DLL FUNCTIONS */
-
- /*****************************************************************************/
- /*****************************************************************************/
-
- /* CALCULATE THE DATE FROM A JULIAN VALUE */
-
- /* This procedure will determine the date from any valid Julian number.
- A valid Julian number will range from 1 to 72743.
-
- If the Julian value is valid, this procedure will fill in the fields
- DateStruct->nYear, DateStruct->nMonth, DateStruct->nDay,
- DateStruct->nLeapYear, DateStruct->nYearDays, and
- DateStruct->nDayOfWeek.
-
- If the Julian value is bad, this procedure will make DateStruct->nError =
- ON, and will return with no further action.
- */
-
- VOID FAR PASCAL CalcNormalDate(Date far *DateStruct)
- {
- int ctr; /* loop counter */
- int accum; /* accumulator */
- long JulianSave = DateStruct->lJulianDate; /* julian-date save */
-
- DateStruct->nError = OFF; /* no error yet */
-
- /* if bad Julian value, */
- if (DateStruct->lJulianDate<1 || DateStruct->lJulianDate>MAX_JULIAN)
- {
- DateStruct->nError = ON; /* flag as date error */
- return; /* return from function */
- }
-
- /* CALCULATE DateStruct->nYear */
- /* determine year number */
- DateStruct->nYear = (int) ((float) DateStruct->lJulianDate / 365.25) +
- BASE_YEAR;
- if (!DateStruct->lJulianDate % 1461L) DateStruct->nYear--;
-
- /* CALCULATE DateStruct->nYearDays */
- /* determine day # in year */
- DateStruct->nYearDays = (int)
- ( DateStruct->lJulianDate -
- (long) ( ((float) (DateStruct->nYear - BASE_YEAR)) * 365.25 )
- );
-
- /* CALCULATE DateStruct->nLeapYear */
- if (DateStruct->nYear % 4) /* determine leap year ? */
- DateStruct->nLeapYear = OFF; /* if remainder, OFFT leap yr */
- else /* else, */
- DateStruct->nLeapYear = ON; /* is a leap year */
-
- /* CALCULATE DateStruct->nMonth */
- accum = 0; /* zero out day accumulator */
- for (ctr = 0; ctr < 12; ctr++) /* month-day accumulate loop */
- {
- accum += MoDaTbl[ctr]; /* add # days in month */
- if (accum >= DateStruct->nYearDays) /* if finished accumulating */
- {
- DateStruct->nMonth = ctr + 1; /* month is identified */
- break; /* exit loop */
- }
- if (ctr==1 && !DateStruct->nLeapYear) /* if Feb of non-leap year */
- accum--; /* decrement accum by 1 */
- }
-
- /* CALCULATE DateStruct->nDay */
- /* determine day in month */
- DateStruct->nDay = MoDaTbl[ctr] - (accum - DateStruct->nYearDays);
-
-
- /* CALCULATE DateStruct->nDayOfWeek
-
- The new DateStruct->nYear, DateStruct->nMonth, and DateStruct->nDay
- is used to recalculate the julian date, using the CalcDayOfWeek()
- function.
-
- If the calculation fails, this function immediately returns. Otherwise,
- the new DateStruct->lJulianDate value is compared to the previous one.
- If the new value is not equal to the old one, the DateStruct->nError flag
- is set, and this function returns.
- */
- CalcDayOfWeek(DateStruct); /* determine day-of-week */
- if (DateStruct->nError) return; /* exit if error */
- if (DateStruct->lJulianDate != JulianSave) /* if DateStruct->
- JulianDate changed, */
- DateStruct->nError = ON; /* there is a bug */
- }
-
-
- /*****************************************************************************/
-
- /* CALCULATE THE DAY OF THE WEEK */
-
- /* This procedure calculates the value for the DateStruct->nDayOfWeek,
- ranging from 0 (Sunday) to 6 (Saturday). The fields DateStruct->nYear,
- DateStruct->nMonth, and DateStruct->nDay should be initialized with valid
- date values before this function is called.
-
- This procedure will exit with no action if any of these three date
- fields (DateStruct->nYear, DateStruct->nMonth, and DateStruct->nDay) has a
- bad value, and the DateStruct->nError field will be set to ON (bad date
- data).
- */
-
- VOID FAR PASCAL CalcDayOfWeek(Date far *DateStruct)
- {
- DateStruct->nDayOfWeek = 0; /* initial value of 0 */
-
- CalcJulianDate(DateStruct); /* calculate julian value */
- if (!DateStruct->nError) { /* if a valid date, */
- /* determine day of week */
- DateStruct->nDayOfWeek = (int) (DateStruct->lJulianDate % 7) + 1;
- if (DateStruct->nDayOfWeek > 6)
- DateStruct->nDayOfWeek = 0;
- }
- }
-
-
- /*****************************************************************************/
-
- /* CALCULATE THE JULIAN VALUE OF A DATE */
-
- /* This procedure calculates the value for the field DateStruct->lJulianDate,
- which is the consecutive day number, starting at 1, from January 1,
- 1901 (Julian date value of 1), and is accurate to February 28, 2100
- (Julian date value of 72743).
-
- This procedure will exit with no action if any of the three date
- fields (DateStruct->nYear, DateStruct->nMonth, and DateStruct->nDay) has a
- bad value, and the DateStruct->nError field will be set to ON (bad date
- data).
- */
-
- VOID FAR PASCAL CalcJulianDate(Date far *DateStruct)
- {
- DateStruct->lJulianDate = 0; /* no julian date yet */
-
- CalcYearDays(DateStruct); /* calc # days into year */
- if (!DateStruct->nError) /* if a valid date, */
- { /* calculate julian date */
- DateStruct->lJulianDate = (
- ((long) (DateStruct->nYear - BASE_YEAR)) * 365
- ) +
- (
- (DateStruct->nYear - BASE_YEAR) / 4
- ) +
- DateStruct->nYearDays;
- }
- }
-
-
- /*****************************************************************************/
-
- /* CALCULATE THE NUMBER OF DAYS INTO THE YEAR */
-
- /* This procedure calculates the value for the field DateStruct->nYearDays,
- which is the "day number" in the year for the date designated by
- the three date fields (DateStruct->nYear, DateStruct->nMonth, and
- DateStruct->nDay). The value of the DateStruct->nYearDays field may range
- from 1 to 366.
-
- This procedure will exit with no action if any of the three date
- fields (DateStruct->nYear, DateStruct->nMonth, and DateStruct->nDay) has a
- bad value, and the DateStruct->nError field will be set to ON (bad date
- data).
- */
-
- VOID FAR PASCAL CalcYearDays(Date far *DateStruct)
- {
- int ctr; /* loop counter */
-
- DateStruct->nYearDays = 0; /* no year days yet */
-
- IsLeapYear(DateStruct); /* determine if leap year */
- if (!DateStruct->nError) { /* if a valid date, */
- if (DateStruct->nMonth > 1) { /* if past January, */
- /* accumulate month-days */
- for (ctr=0; ctr < DateStruct->nMonth-1; ctr++)
- {
- DateStruct->nYearDays += MoDaTbl[ctr];
- }
- }
- DateStruct->nYearDays += DateStruct->nDay; /* add day-in-month */
- /* if past Feb, non-leap yr, */
- if (DateStruct->nMonth > 2 && !DateStruct->nLeapYear)
- DateStruct->nYearDays -= 1; /* take one day away */
- }
- }
-
-
- /*****************************************************************************/
-
- /* IS THIS A LEAP YEAR ? */
-
- /* This procedure determines whether the date designated by the
- three date fields (DateStruct->nYear, DateStruct->nMonth, and
- DateStruct->nDay) falls within a leap year. If it does, then the field
- DateStruct->nLeapYear will be set to ON; otherwise, it will be set to 0.
-
- This procedure will exit with no action if any of the three date
- fields (DateStruct->nYear, DateStruct->nMonth, and DateStruct->nDay) has a
- bad value, and the DateStruct->nError field will be set to ON (bad date
- data).
- */
-
- VOID FAR PASCAL IsLeapYear(Date far *DateStruct)
- {
- CheckValidDate(DateStruct); /* is this a valid date ? */
- if (!DateStruct->nError) { /* if a valid date, */
- if (DateStruct->nYear % 4) /* determine if leap year */
- DateStruct->nLeapYear = OFF; /* if remainder, OFFT leap yr */
- else /* else, */
- DateStruct->nLeapYear = ON; /* is a leap year */
- }
- }
-
-
- /*****************************************************************************/
-
- /* VERIFY THAT DATE FIELDS CONTAIN VALID VALUES */
-
- /* This procedure checks to see whether the date designated by the
- three date fields (DateStruct->nYear, DateStruct->nMonth, and
- DateStruct->nDay) is a valid date, but does not check for leap years.
-
- If the date field data is valid, the field DateStruct->nError will contain
- an OFF upon exit. Otherwise, this field will contain an ON.
- */
-
- VOID FAR PASCAL CheckValidDate(Date far *DateStruct)
- {
- DateStruct->nError = OFF; /* no date error yet */
- if /* test date values */
- (
- DateStruct->nYear < BASE_YEAR ||
- DateStruct->nYear > CEIL_YEAR ||
- DateStruct->nMonth < 1 ||
- DateStruct->nMonth > 12 ||
- DateStruct->nDay < 1 ||
- DateStruct->nDay > 31 ||
- (DateStruct->nYear==CEIL_YEAR && DateStruct->nMonth>=2 &&
- DateStruct->nDay>28)
- )
- DateStruct->nError = ON; /* signify date error */
- if (!DateStruct->nError)
- if (DateStruct->nDay > MoDaTbl[DateStruct->nMonth-1])
- DateStruct->nError = ON;
- }
-
-
- /*****************************************************************************/
-
- /* ONE-TIME GLOBAL DLL-INIT FUNCTION */
-
- int FAR PASCAL LibMain (HANDLE hInstance,
- WORD wDataSeg,
- WORD cbHeapSize,
- LPSTR lpszCmdLine)
- {
- /* Perform DLL initialization
- .
- .
- .
- */
-
- if (cbHeapSize != 0) /* If DLL data seg is MOVEABLE */
- UnlockData(0); /* unlock the data seg */
-
- return(1); /* Initialization successful,
- otherwise, return(0); */
- }
-
-
- /*****************************************************************************/
-
- /* ONE-TIME GLOBAL DLL-SHUTDOWN FUNCTION */
-
- WORD FAR PASCAL WEP(int nParameter)
- {
- if (nParameter == WEP_SYSTEM_EXIT)
- {
- /* System shutdown in progress. Respond accordingly. */
- return(1);
- }
- else
- {
- if (nParameter == WEP_FREE_DLL)
- {
- /* DLL-use count is zero. Every application that had loaded the
- DLL has freed it. */
- return(1);
- }
- else
- {
- /* Undefined value. Ignore. */
- return(1);
- }
- }
- }
-