Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Calculate Nth day of month, eg MLK day is 3rd Monday in January. . . 2

Status
Not open for further replies.

dantheinfoman

Programmer
May 5, 2015
131
US
Hi All,

Just nerding out on a project and wondered if anyone knows a good mathematical way to get the Nth Weekday of a month. As in my title, for example, Martin Luther King holiday falls on the 3rd Monday in January. I looked at thread184-712215, but I'm afraid I'm not as great at math as some of you folks, so if you have any ideas, I'd be thrilled to hear them.

This kind of this happens a lot in Holidays. I think Thanksgiving in US is 4th Thursday in November, etc.

Thanks!

Dan
 
Dan, you're in luck. A client of mine wrote a program to do exactly what you want, that is, to calculate the dates of all kinds of holidays and other notable dates. You can download it here:
Here's an extract from the program for Martin Luther King Day:

Code:
counter = 0
TheMonth = 1
FOR daytoseek = 1 TO 31
  TheDate = DATE(YEAR(DATE()),TheMonth,daytoseek)
  IF CDOW(TheDate) = 'Monday'
    add_date = TheDate	
    counter = counter + 1
    IF counter = 3
      EXIT
    ENDIF
  ENDIF
ENDFOR

At the end of the above loop, add_date will contain the required date.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Oh my gosh,

all this for week of year of the current day minus week of year for the 1st of the month?
It's simply an offset calculation. And it doesn't answer your question.


Edit: Just to be very clear: With this I was referring to the other thread you linked to, dan, not to Mike's answer.


Anyway, take it from thread184-1141890, either Marcia or my function solve that problem more general and with my implementation
NthWeekDayOfMonth(2, 3, 1, 2015) wold give you 3rd (3) Monday (2) of January (1) this year.

Maybe switch parameters as you like them better, eg start with tnN (or tnWhich) and put the weekday second.

Bye, Olaf.

 
Here's a more generic vesion. This will find the Nth occurrence of any day in any month.

Code:
FUNCTION NthDayOfMonth
LPARAMETERS tnYear, tnMonth, tnDayToFind, tnNth

* Finds the Nth weekday in a given month (e.g. 3rd Monday of April 2016)

* Parameters: 
* - Year number; must be at least 1753 (e.g 2016)
* - Month number; January = 1, etc.
* - Day to find, Sunday = 1, etc
* - Occurrence to find (e.g. 3 to find the 3rd instance of the specified day).
* So to find the 3rd Monday of April 2016, you would pass 2016, 4, 2, 3.

* Returns the day number within the month; returns 0 if any of the parameters 
* is out of range, or if the date doesn't exist (e.g. if you ask for the 5th 
* Friday in a month that only has four Fridays).

LOCAL lnCount, lnI,lnDaysInMonth, lnReply

lnReply = 0

* Deal with out-of-range parameters
IF NOT BETWEEN(tnYear, 1753, 9999) OR ;
   NOT BETWEEN(tnMonth, 1, 12) OR ;
   NOT BETWEEN(tnDayToFind, 1, 7) OR ;
   NOT BETWEEN(tnNth, 1, 5)
   
   RETURN lnReply
   
ENDIF 

* How many days in the month?
lnDaysInMonth = DAY(GOMONTH(DATE(tnYear, tnMonth, 1), 1) - 1)

* Loop throuth the days in the month
lnCounter = 0
FOR lnI = 1 TO lnDaysInMonth
   IF DOW(DATE(tnYear, tnMonth, lnI)) = tnDayToFind
     lnCounter = lnCounter + 1 
     IF lnCounter = tnNth
       * This is the one we want
       lnReply = lnI
       EXIT
     ENDIF
   ENDIF
ENDFOR 

RETURN lnReply

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Just to go one step further ...

I was thinking of extending the above function to also find the last occurrence of a given day in a given month (e.g. the last Friday in December 2015). But it occurred to me there is any easy way to handle that:

So, the last Friday of December 2015 would be given by this expression:

Code:
MAX(NthDayOfMonth(2015, 12, 6, 5), NthDayOfMonth(2015, 12, 6, 4))

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top