1  Introduction

Fun With UDFs

Richard Bunter

This month's edition of Fun With UDFs brings you  three more date
functions for your already overflowing library.  



2  Article

Suppose that you wanted a function that would tell you the day of  the
week of a date a few months from now.  You may ask "why?"  Just  to do
it, that's why!  Okay, here's a better rationale: for making 
appointments in advance, but only on weekdays.  It wouldn't do to 
schedule a Sunday appointment, would it?  Everybody else would be 
bowling.

At any rate, here are three functions that will help you manage dates 
more effectively:

AddMo returns the date of a date plus so many months. AddWk returns
the date of a date plus so many weeks.  AddYr returns the date of a
date plus so many years.

The syntax in using each is the same; they all take two arguments: 
the date (in date format) and how many to add.  Also, they are all 
written on the assumption that the AMERICAN date format is being
used.  You  may want to re-write them if that's not true. 
Alternatively, you  could test for which format is in use with a
function from last month's  issue: SETD.  Then you could set the date
to American, do what you  need to do with dates and reset it back to
whatever.

To return to our scenario:  if you wanted to know which day two
months  from now fell on, you first need to know the date two months
from  now.  Oh, sure, you know the date two months from now, but try
to  get practically any language to tell you.  There is no function
in  the dBASE language to increment the month (or week or year), so
we  create one.  Now we can do this:

. mDate = CTOD("01/12/89")  . ? AddMo(mDate,2) 03/12/89

Now that we know how to get the date, we just ask for the character 
day of that date by using CDOW(), a built-in function, like this:

. ? CDOW(AddMo(mDate,2))
 Sunday

Or we can test for the number of the day-of-the-week by using the 
DOW() function.

. ? DOW(AddMo(mDate,2))
      1.00

Now, we can test for improper days and increment the date
accordingly.  For  example, after entering an appointment date, you'd
like to know the  call-back date for two months later.  It has to be
on a week day,  so if it falls on a Saturday, move it to the previous
Friday and if  it falls on a Sunday, move it to the following Monday. 
Here's a little  sample program (that's made up mostly of comments):

SET PROC TO Lib  CLEAR  Appoint = DATE()  @ 10,10 SAY "Enter your
appointment date" GET Appoint  READ Call_Back = AddMo(Appoint,2)  &&
Add two months to Appoint. *--- Check for the day of the week; if it's
a Saturday, *    subtract<N>one from the date.  If it's a Sunday, *   
add one to the date. *    We're going to do this by comparing the day
of the *    week that<N>the day falls on ("DOW(Call_Back)") to an *   
offset table ("010000000000-1"), then adding the *    number we find
in the table to the call back date.  *    The table is composed of
seven two-digit numbers,  *    one for each day of the week.  We
multiply the DOW() *    by two (because we're looking at a string of
*    two-digit numbers) then subtract one. The resultant *    number
is where we look in the table.   *    For example, if our date is a
Saturday, DOW() will *    return a 7.  We multiply 7 * 2 to get 14,
subtract 1 *    to get 13.  So, find two characters at the 13th *   
position in the table, which returns -1.  *    Finally, our Call_Back
date = Call_Back - 1. *    This, too, can be incorporated into a
function. Call_Back = Call_Back ;
        + VAL(SUBSTR("010000000000-1",DOW(Call_Back)*2-1,2)) @ 10,10
SAY "Call back on " + CDOW(Call_Back) ;
        + ", " + DTOC(Call_Back) *--- The end.

You've probably figured out by now, if you didn't know before reading 
this article, that adding a number to a date will increment the date 
by that number of days.

 



3  Lib.PRG

Lib.PRG
* Test Library

FUNCTION AddMo
* Increments <date> by <n> months.

PARAMETERS date,add
RETURN(CTOD(STR(VAL(LEFT(DTOC(date),2))+add,2) + RIGHT(DTOC(date),6)))
* EOF: AddMo


FUNCTION AddWk
* Increments <date> by <n>weeks.

PARAMETERS date,add
RETURN(date + 7*add)
*EOF: AddWk


FUNCTION AddYr
* Increments <date> by <n> years.
PARAMETERS date,add
RETURN(CTOD(LEFT(DTOC(date),6) + STR(YEAR(date) + add)))
* EOF: AddYr
                                                                               