A Method For Determining A (Very) Specific Day Of The Month:
A recent discussion on the U2UG.org mail list concerned hypothetical questions to be asked of someone interviewing for a programming job. One proposed question was "How do you determine the last Thursday in a month?". This reminded me of one of the first functions I ever learned in college (COC3110 I think (UF 1983)). The premise of the function is that certain months have 30 days and the rest have 31 (except for February, which usually has 28 and sometimes 29). Further expanding the rules we know that, except for February, the odd months from January through July have 31 days while the even months have 30 days. The rest of the year is reversed. Even months have 31 days and odd months have 30 days. Finally we know that every four years is a leap year (unless it falls on a century year).
With these rules and constraints the function looks like this:
Note: All programming displayed on this site is for illustrative purposes only. Use at your own risk.
function days.in.month(date)
if date = "" then date = oconv(date(),"D4/")
month = date[1,2]
year = date[7,4]
lastDOM = ""
if month < 8 then
* January through July
if month = 2 then
* February
if mod(year,4)=0 and mod(year,100)<>0 then
lastDOM = 29 ;* Feb leap year
end else lastDOM = 28 ;* Feb non-leap year
end else
* Not February
if mod(month,2)=0 then
lastDOM = 30 ;* even month Jan to Jul
end else lastDOM = 31 ;* odd month Jan to Jul
end
end else
* August through December
if mod(month,2)=0 then
lastDOM = 31 ;* even month Aug to Dec
end else lastDOM = 30 ;* odd month Aug to Dec
end
return (lastDOM)
end
Note: There is no consideration in this example for handling a malformed date. The date format I used is mm/dd/yyyy. The goal of this exercise is to highlight the simple math required to apply to consistent rules, that results in a bullet-proof algorithm.
Programmers used to have to be concerned with optimization to reduce CPU cycles. Except for very few examples (loops requiring millions of iterations, financial batch operations, etc.) programming today can solve similar types of problems with case statement blocks or even many nested if-then-else blocks.
Here is an example:
function days.in.month(date)
if date = "" then date = oconv(date(),"D4/")
month = date[1,2]
year = date[7,4]
lastDOM = ""
begin case
case month=1; lastDOM=31
case month=2 and mod(year,4)=0 and mod(year,100)<>0
lastDOM=29 ;* Leap year
case month= 2; lastDOM=28 ;* Non-leap year
case month= 3; lastDOM=31
case month= 4; lastDOM=30
case month= 5; lastDOM=31
case month= 6; lastDOM=30
case month= 7; lastDOM=31
case month= 8; lastDOM=31
case month= 9; lastDOM=30
case month=10; lastDOM=31
case month=11; lastDOM=30
case month=12; lastDOM=31
end case
return (lastDOM)
end
Or better still only check for February and the 30 day months:
function days.in.month(date)
if date = "" then date = oconv(date(),"D4/")
month = date[1,2]
year = date[7,4]
lastDOM=31
begin case
case month= 2 and mod(year,4)=0 and mod(year,100)<>0
lastDOM=29 ;* Leap year
case month= 2; lastDOM=28 ;* Non-leap year
case month= 4; lastDOM=30
case month= 6; lastDOM=30
case month= 9; lastDOM=30
case month=11; lastDOM=30
end case
return (lastDOM)
end
Note: There is no consideration in this example for handling a malformed date. The date format I used is mm/dd/yyyy.
This second example is the cleanest (in my humble opinion) and easier to understand. Running VLIST on the object code implies the
Programmers in today's development environment who solve problems using complex methods like the first example above are, hopefully, the exception to the norm.
Having shown two different ways (out of doubtless many more) to determine the last day of the month, I will complete the exercise by showing how I would then determine the last Thursday in any given month:
subroutine get.last.thursday(date,last.thursday.in.month)
deffun DAYS.IN.MONTH(ax)
month = date[1,2]
year = date[7,4]
num.days.in.month = DAYS.IN.MONTH(date)
y = 0
loop
test.date = month:"/":num.days.in.month:"/":year
until mod(iconv(test.date,"D4/")-y,7)=4
y=y+1 ;* only increment the day counter if not Thursday
repeat
last.thursday.in.month = month:"/":num.days.in.month-y:"/":year
return
end
Note: As before, there is no consideration in this example for handling a malformed date. The date format I used is mm/dd/yyyy. The bit of math that is needed to determine the day of the week is mod(date,7). The date must be in internal format (number of days since December 31, 1967). Using this formula we know:
Sunday = 0
Monday = 1
Tuesday = 2
Wednesday = 3
Thursday = 4
Friday = 5
Saturday = 6
Now we can determine the date of the month for the last occurrence of the seven days of the week.
To answer the job interview question, it would probably be sufficient to explain how you would determine the number of days in a month and how you would determine if a date is a Thursday. Then a brief description of a program to calculate the number of days in the month, and working backwards until the date is a Thursday. I think this would take no more than one or two minutes to explain at the most.
If you want to know if the person has been programming in MV DBMS systems for 20 years or more ask them "What is day ten thousand?"
No comments:
Post a Comment