0

I need to get the next 4 Thursdays with javascript, and append the result into a select box but if the current date is past Sunday, don't get the first Thursday (start a week later).

So for example:


Current date = Saturday 12th June 2021

Get Next 4 Thursdays: 17th June 2021, 24th June 2021, 1st July 2021, 8th July 2021.


Current Date = Tuesday 15th June 2021 -- Don't get 17th June 2021, so list would be:

24th June 2021, 1st July 2021, 8th July 2021, 15th July 2021.


I had some code originally that would get the thursdays for X amount of months, but this isn't quite what I want, as it gets all thursdays in one month, rather than the next 4 thursdays. I'm guessing I can reuse the get day of the week code, and modify it to just get the next 4 days... then somehow filter if the date is past Sunday?

function getNextMonths(num) {

    let current = new Date();
    let months  = [];

    for (let i = 0; i <= num; i++) {

        let next = new Date();

        next.setDate(1); // First day... 
        next.setMonth(current.getMonth() + i); //...of next month

        months.push(next);
    }

    return months;
}

function getDayOfWeek(num_week_day, dates) {

    let days = [];

    var today = new Date();

    for (let i = 0; i < dates.length; i++) {

        // Evaluate current month
        
        let current = {

            year: dates[i].getFullYear(),
            month: dates[i].getMonth()
        };

        current.days = new Date(current.year, current.month + 1, 0).getDate();
        
        // Loop & evaluate days 
        
        for (let d = 1; d <= current.days; d++) {

            let date = new Date(current.year, current.month, d);

            if (date.getDay() == num_week_day) {
                if(date.getTime() > today.getTime()){
                    days.push(date);
                }
            }
        }
    }

    return days;
}

//Convert to Nice looking Date
function dateToString(date){
    return date.toLocaleDateString("en-GB", { 
    dateStyle: 'full'
    });
}

//Output date as mm/dd/yyyy for ouput value
function dateToValue(date){
return date.toLocaleDateString("en-GB", { 
  year: "numeric",
  month: "short",
  day: "numeric",
});
 
}

// Get all Thursdays (4th day of the week) within the next 2 months.

    var select = document.getElementById("arr");
    var elmts = getDayOfWeek(4, getNextMonths(1));

    // Main function
    jQuery( document ).ready(function() {

        jQuery('#sub_start_date').find('option').remove();

        jQuery.each(elmts, function(i, p) {
            
                jQuery('#sub_start_date').append(jQuery('<option></option>')
                        .val(dateToValue(p)).html(dateToString(p)));
       
            
        });
    });
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
user2115227
  • 147
  • 2
  • 9
  • 24
  • After reading your post several times it is still unclear for me what you want to achive (the text and headline confuses me a little bit). So review your question and mark or add your expected output. Neverless, I can give you a hint: "Past sunday" is when the daynumber is greater than zero and smaller than fore. Friday is five, Saturday is six and Sunday is zero. – Reporter Jun 15 '21 at 11:03
  • Sorry for the confusion. I need to get the next 4 Thursdays from today's date... BUT if today's date is after Sunday, get the next 5 Thursdays and exclude the first one. (For context: The dropdown is a delivery date selection, but if it's past Sunday, the next Thursday is too soon for delivery, so needs to be cut off). Is that clearer? – user2115227 Jun 15 '21 at 11:05
  • Yes it is much clearer. – Reporter Jun 15 '21 at 11:07
  • A question: Does your code work in general, exclude of your requirement? – Reporter Jun 15 '21 at 11:20
  • My code works in the following way: It gets the thursdays, but only for a set amount of months. So if I call: getDayOfWeek(4, getNextMonths(1)); - it shows all the thursdays in June and July, from the current date. On the current date (15th Jun), it would show June 17th to July 29th. But I need to just show the next 4 thursdays, from the current date... then exclude the cut-off date – user2115227 Jun 15 '21 at 12:15

1 Answers1

0

In my eyes your code is incomplete so I cannot run in my own enviroment. My suggestion for you is though quite simple:

You store your dates in an array elmts and you loop through it to create all option elements.

My suggestion is:

  • Create always five dates
  • Depends on the daynumber remove the first or the last entry from array elmts. Javascript offers two methods for it:

The method .shift() removes the first element from an array (see also https://www.w3schools.com/jsref/jsref_shift.asp ).

The method .pop() removes the last element from an array (see also https://www.w3schools.com/jsref/jsref_pop.asp ).

Based on https://gomakethings.com/how-to-get-the-date-for-a-specific-day-of-the-week-with-vanilla-js/

My code:

/* Some nassecary preconditions */
var datebase = new Date();
var targetDaynumber = 4;
var currentDiff = new Date().getDay();

/* Calculates a timestamp based on your wished weekday */
var getNextDay = function (basedate) {

    // The current day
    var now = basedate.getDay();

    var diff = targetDaynumber - now;
    diff = diff < 1 ? 7 + diff : diff;

    // Get the timestamp for the desired day
    var nextDayTimestamp = basedate.getTime() + (1000 * 60 * 60 * 24 * diff);

    // Get the next day
    return new Date(nextDayTimestamp);
};
/* ------------------------------------------------- */

/* Creating five timestamps */
var dateArray = [];
var loopindex = 5;
for (x = 0; x < loopindex; x++)
{
    datebase = getNextDay(datebase);
    dateArray.push(datebase);
}

/* Calculating the timegap */
if (currentDiff <= targetDaynumber) {
    //Timegap is too small, remove the earliest timestamp
    dateArray.shift();
} else {
    //Timegap is ok, the fith element is not nassecary
    dateArray.pop();
}
Reporter
  • 3,897
  • 5
  • 33
  • 47
  • Thanks, this is kind of useful, but the code doesn't seem to work when I add it. I wonder if you could provide the full code, ignoring what I already have? What I have is probably not needed anymore, but rather can be streamlined to just get the next 5 thursdays, and shift or pop depending on if it's past Sunday. – user2115227 Jun 15 '21 at 14:22
  • @user2115227 I updated my answer. Have a look. – Reporter Jun 21 '21 at 09:26