GDATE.C


/******************************************************************************\
* This is a part of the Microsoft Source Code Samples.
* Copyright 1993 - 1998 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/

/****************************** Module Header *******************************
* Module Name: GDATE.C
*
* Contains date conversion functions.
*
* Functions:
*
* gdi_isleap()
* gdate_daytodmy()
* gdate_dmytoday()
* gdate_monthdays()
* gdate_weeklyday()
*
* Comments:
*
****************************************************************************/

#include <windows.h>
#include <string.h>

#include "gutils.h"


BOOL gdi_isleap(LONG year);

/*---static data--------------------------------------------*/

int monthdays[] = {
31,
28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31
};


/***************************************************************************
* Function: gdate_daytomy
*
* Purpose:
*
* converts day to d/m/y
*/
void APIENTRY
gdate_daytodmy(LONG days, int FAR* yrp, int FAR* monthp, int FAR* dayp)
{
int years;
int nleaps;
int month;
int mdays;

/* get number of completed years and calc leap days */
years = (int) (days / 365);
days = days % 365;
nleaps = (years / 4) - (years / 100) + (years / 400);
while (nleaps > days) {
days += 365;
years--;
nleaps = (years / 4) - (years / 100) + (years / 400);
}
days -= nleaps;

/* add one year for current (non-complete) year */
years++;


/* current month */
for (month = 0; month < 12; month++) {
mdays = monthdays[month];
if (gdi_isleap(years) && (month == 1)) {
mdays++;
}
if (days == mdays) {
days = 0;
month++;
break;
} else if (days < mdays) {
break;
} else {
days -= mdays;
}
}
/* conv month from 0-11 to 1-12 */
if (monthp != NULL) {
*monthp = month+1;
}
if (dayp != NULL) {
*dayp = (int) days + 1;
}
if (yrp != NULL) {
*yrp = years;
}
}


/***************************************************************************
* Function: gdate_dmytoday
*
* Purpose:
*
* converts d/m/y to a day
*/
LONG APIENTRY
gdate_dmytoday(int yr, int month, int day)
{
int nleaps;
int i;
long ndays;

/* exclude the current year */
yr--;
nleaps = (yr / 4) - (yr / 100) + (yr / 400);

/* in any given year, day 0 is jan1 */
month--;
day--;
ndays = 0;
for (i = 0; i < month ; i++) {
ndays += monthdays[i];
if (gdi_isleap(yr+1) && (i == 1)) {
ndays++;
}
}
ndays = ndays + day + nleaps + (yr * 365L);
return(ndays);
}

/***************************************************************************
* Function: gdate_monthdays
*
* Purpose:
*
* Gets number of days in month
*/
int APIENTRY
gdate_monthdays(int month, int year)
{
int ndays;

ndays = monthdays[month - 1];
if (gdi_isleap(year) && (month == 2)) {
ndays++;
}
return(ndays);
}

/***************************************************************************
* Function: gdate_weekday
*
* Purpose:
*
* Gets the day of the week
*/
int APIENTRY
gdate_weekday(long daynr)
{
return((int) ((daynr + 1) % 7));
}


/***************************************************************************
* Function: gdi_isleap
*
* Purpose:
*
* Determines whether the year is a leap year
*/
BOOL
gdi_isleap(LONG year)
{
if ( ((year % 4) == 0) &&
(((year % 100) != 0) ||
((year % 400) == 0))) {
return TRUE;
} else {
return FALSE;
}
}