Free Web Hosting Provider - Web Hosting - E-commerce - High Speed Internet - Free Web Page
Search the Web


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Calculating the number of days in a month
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The number of days each month is as follows;

Name    Number  NumerofDays
---------------------------------------------
Jan     01      31
Feb     02      29 if leap year, otherwise 28
Mar     03      31
Apr     04      30
May     05      31
Jun     06      30
Jul     07      31
Aug     08      31
Sep     09      30
Oct     10      31
Nov     11      30
Dec     12      31
---------------------------------------------

So given that %MM% holds the current month
you almost have a very simple solution in;

SET _=31
FOR %%_ IN (04 06 09 11) DO IF %MM%==%%_ SET _=30

%_% is now the correct number of days in the month
for all of the months except February.

At least we know that we could have the next line;

IF NOT %MM%==02 %RET%

February makes things a bit more difficult for us,
we need to check the year and find out whether or
not it is a leap year in order to get the correct
answer.

A leap year occurs when these conditions are satisfied;

(i) The year must be divisible by 4

(ii) If the year is divisible by 100 then it
     must be divisible by 400 also.

Using the year variables %YH% and %YL% (YH=century,
YL=year mod100) it is simple to see that there
are only 2 cases to check;

(i) If YL=0 then  ISLEAPYEAR:= { YH divisible by 4 }
(ii) If YL!=0 then ISLEAPYEAR:= { YH,YL divisible by 4 }

(ii) can be further simplified by noticing that if
the least 2 significant digits of a value are divisible
by 4 then the whole number is divisible by 4 (This is
due to the fact that the number YEAR can be written
as YH*100+YL = (YH*25)*4+YL )

Then we have;
(ii) If YL!=0 then  ISLEAPYEAR:= { YL divisible by 4 }

How to check divisibility by 4?? Easy, since we now know
we only have to check a 2 digit value a simple exhaustive
check on all the 25 possibilities can be done with a
FOR loop;

FOR %%_ IN (00 04 08 12 16 20 24 28 32 36 40 44) DO IF %_%==%%_ SET _=ABC
FOR %%_ IN (48 52 56 60 64 68 72 76 80 84 88 92 96) DO IF %_%==%%_ SET _=ABC
IF %_%==ABC ECHO VALUE IS DIVISIBLE BY 4!

Now, look again at the rules we have;

(i) If YL=0 then  ISLEAPYEAR:= { YH divisible by 4 }
(ii) If YL!=0 then  ISLEAPYEAR:= { YL divisible by 4 }

You may notice how similar they are. In fact they could be
rewritten into one;

   @=%YL%
   IF YL=0 then @=%YH%
   ISLEAPYEAR:= { @ divisible by 4 }

This works out very nicely in DOS batch code;

:: get value to check, either YL or YH

SET _=%YH%
IF NOT %YL%==00 SET _=%YL%

:: a little fixup, 29 is used as the marker for divisibility by 4
:: check succeeding so we don't want it to be a possible input value
:: changing a value 29 to 01 here won't change the result, it's
:: still not divisible by 4

IF %_%==29 SET _=01

:: check %_% for divisibility by 4, if (and only if) it is divisible
:: by 4 will the 2 loops complete with %_%=29

FOR %%_ IN (00 04 08 12 16 20 24 28 32 36 40 44) DO IF %_%==%%_ SET _=29
FOR %%_ IN (48 52 56 60 64 68 72 76 80 84 88 92 96) DO IF %_%==%%_ SET _=29

:: If its not a multiple of 4 then the number of days in Feb
:: will be 28

IF NOT %_%==29 SET _=28


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The complete subroutine
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


::************************************************************
::* DIMTH  - CALCULATE DAYS IN MONTH                         *
::* Entry:          %YH%,%YL%=YEAR %MM%=MONTH                *
::* Exit:           %_%=DAYS IN MONTH                        *
::* Last Modified:  30/10/00                                 *
::* Compatibility:  DOS 5+       (Tested: DOS 7)             *
::* Notes:  This is optimised version with leap year routine *
::*         integrated into it.                              *
::************************************************************

:DIMTH
SET _=31
FOR %%_ IN (04 06 09 11) DO IF %MM%==%%_ SET _=30
IF NOT %MM%==02 %RET%
SET _=%YH%
IF NOT %YL%==00 SET _=%YL%
IF %_%==29 SET _=01
FOR %%_ IN (00 04 08 12 16 20 24 28 32 36 40 44) DO IF %_%==%%_ SET _=29
FOR %%_ IN (48 52 56 60 64 68 72 76 80 84 88 92 96) DO IF %_%==%%_ SET _=29
IF NOT %_%==29 SET _=28
%RET%


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~