Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 4 of 4
  1. #1
    New to the CF scene
    Join Date
    Oct 2011
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Need JS code to find nth weekday of month

    Hello:

    Many apologies if this is not an appropriate question here... but I have googled my fingers raw and haven't been able to find a script to do what I am looking for. I have little experience with JavaScript.

    I have a VBA script (code at the end of this post) that returns the date corresponding to a given occurrence of a given weekday, e.g. Ask it for the 3rd Tuesday in October 2012 and it gives you 16-OCT-2012. It defaults to current year if you don't pass the Year argument.

    It's a pretty simple script, but I need to either finds something in JavaScript that does the same thing, or convert the VBA code to JavaScript. I can't help but think that many people have already written scripts that do this. Any chance someone can lead me in a productive direction here?

    Regards,

    Steve Jones

    (update - I noticed the code didn't retain its formatting, so I attached a text file)

    -begin VBA code-
    Public Function xdate(m As Integer, n As Integer, wd As Integer, Optional y As Integer = 0) As Date
    '// m = 1-12 (Jan-Dec), n = 1-5 (1st-4th, last), wd = 1-7 (Sun-Sat), y = 1900-9999 or left blank for current year
    Select Case y
    Case 0 ' // Default. Use the current year.
    y = year(Date)
    Case 1900 To 9999 ' // treat the value as an explicit year
    Case -100 To -1, 1 To 100 ' // treat the value as an offset to be applied to the current year
    y = year(Date) + y
    Case Else
    ' // invalid value. Insert whatever error processing you like.
    End Select
    Select Case n
    Case 1 To 4 '// first through fourth
    Case 5 '// last. We need to check to see it fell within the month specified, if not, use 4.
    xdate = DateSerial(y, m, (8 - weekday(DateSerial(y, m, 1), (wd + 1) Mod 8)) + ((n - 1) * 7))
    If month(xdate) <> m Then
    n = 4
    End If
    Case Else
    ' // invalid value - insert error processing code here if you like.
    ' // Probably should check the other arguments as well.
    End Select
    xdate = DateSerial(y, m, (8 - weekday(DateSerial(y, m, 1), (wd + 1) Mod 8)) + ((n - 1) * 7))
    End Function
    -end vba code-
    Attached Files Attached Files
    Last edited by SteveJonesMO; 10-07-2011 at 10:18 PM.

  • #2
    Regular Coder
    Join Date
    Sep 2011
    Location
    Sweden
    Posts
    154
    Thanks
    1
    Thanked 22 Times in 22 Posts
    Try
    Code:
    var getDate = function(index,weekday,month,year){
      // index what occurence of the weekday we look for (1 and upwards)
      // weekday 0-6  (= Sunday - Monday)
      // month 1-12   (= January - December) optional defaults to current month
      // year (a four digit number) optional defaults to current year
      var now = new Date(), co = 1, result;
      month = month || now.getMonth() + 1;
      year = year || now.getFullYear();
      do {
        result = new Date(year,month-1,co);
        result.getDay() == weekday && index--;
        co++;
      }
      while (index > 0);
      return result
    };
    Last edited by ironboy; 10-07-2011 at 10:39 PM.

  • #3
    Regular Coder
    Join Date
    Sep 2011
    Location
    Sweden
    Posts
    154
    Thanks
    1
    Thanked 22 Times in 22 Posts
    Or, if you want an "error" if the index is not within the month (seems that's what your VB Script does), this will return false when "out of range":

    Code:
    var getDate = function(index,weekday,month,year){
      // index what occurence of the weekday we look for (1 and upwards)
      // weekday 0-6  (= Sunday - Monday)
      // month 1-12   (= January - December) optional defaults to current month
      // year (a four digit number) optional defaults to current year
      var now = new Date(), co = 1, result;
      month = month || now.getMonth() + 1;
      year = year || now.getFullYear();
      do {
        result = new Date(year,month-1,co);
        result.getDay() == weekday && index--;
        if(result.getMonth() + 1 != month || index + co < 2){return false};
        co++;
      }
      while (index > 0);
      return result
    };

  • #4
    Regular Coder
    Join Date
    Sep 2010
    Location
    Far far away
    Posts
    122
    Thanks
    0
    Thanked 16 Times in 16 Posts
    I just wanted to practise my brains I am not sure that the requested feature is frquently used that so you could not find the good implementation both javascript or others.

    Let's consider your issue from another point of view. There are many coupled methods named as setXXX/getXXX (for example, setDate/getDate to set and get the day number in month). But having the getDay method (to retrieve the weekday of the date) we do not have setDay to set it. So let's try to implement it. We will pass the day of the week as a mandatory argument and the optional number of the wek in the month. I have put many comments to describe what happens there in detail. Feel free to squeeze the code deleting them.

    Code:
    /**
     * Sets the day of the week value of the Date object using local time. 
     * 
     * The weekday is an integer between 0 and 6 representing the day of 
     * the week and corresponds to the day of the week as follows:
     * 0 - Sunday
     * 1 - Monday
     * 2 - Tuesday
     * 3 - Wednesday
     * 4 - Thurday
     * 5 - Friday
     * 6 - Saturday
     * 
     * If the second argument is defined then it sets to the week number 
     * when this day of the week occurs. It is the number of the week 
     * (the first week of the month is 0). 
     *
     * @param	Integer	Required. A numeric value of the day of the week. 
     * @param	Integer	Optional. A numeric value of the week of the month. 
     * @param	Date
     * @access	public
     */
    Date.prototype.setDay = function(w, n)
    {
    	// Get the reference to the Date object
    	var x = this;
    	// Set the date to the first day of the month
    	x.setDate(1);
    	// Calculate the distance to the nearest required weekday
    	var d = w - x.getDay() + 1;
    	if ( d < 0 ) {
    		d += 7;
    	}
    	// Calculate the date corresponding to the required weekday
    	d += (n || 0) * 7;
    	// Set the date and return the result as all methods do
    	return x.setDate(d);
    };
    
    for (var i = 1; i <= 31; i++) {
    	var x = new Date(2012, 9, i);
    
    	// Set 3rd Tuesday in October 2012
    	var y = new Date(2012, 9, i);
    	y.setDay(2, 2);
    
    	alert([x, y]);
    }
    Last edited by siberia-man; 10-08-2011 at 02:59 AM. Reason: some little bit changes in the comments


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •