24
\$\begingroup\$

Given a particular Date, want to find the next occurring Friday. I solved it using the below code. Various tested scenarios work good for me.

  1. Are there any boundary conditions the code might break?
  2. Can it be written any better?

function dates() {
    var dayOfWeek = 5;//friday
    var date = new Date(2013, 10, 13);
    var diff = date.getDay() - dayOfWeek;
    if (diff > 0) {
        date.setDate(date.getDate() + 6);
    }
    else if (diff < 0) {
        date.setDate(date.getDate() + ((-1) * diff))
    }
    console.log(date);
}
\$\endgroup\$
4
  • \$\begingroup\$ Do you mean the next friday following the date, or the next friday on the date or later? The code will do the latter. There is a bug i the code, you are using 6 instead of diff if diff > 0. The code (-1) * diff can be written simpler as -diff, but then of course + ((-1) * diff) can be written as - diff. \$\endgroup\$
    – Guffa
    Oct 30, 2013 at 18:50
  • \$\begingroup\$ yes the later.. that's wat i want to find. On 6. The logic is for saturday. If diff > 0 that means i can only saturday. saturday + 6 gives you next consecutive firday \$\endgroup\$ Oct 31, 2013 at 8:42
  • \$\begingroup\$ Then the implementation only works for friday, while the question title specifies that it should work for any dayOfWeek value. \$\endgroup\$
    – Guffa
    Oct 31, 2013 at 12:52
  • \$\begingroup\$ you are right 6 is specific to friday! :) \$\endgroup\$ Nov 1, 2013 at 2:11

4 Answers 4

24
\$\begingroup\$

Since you say "Given a particular Date" and "next occurring Friday (or any dayOfWeek)" I think both should be parameters to your function. As it is written, it will only return November 15 always.

function dates(date, dayOfWeek)

But then you should check that dayOfWeek is in range (0-6, thanks SridharVenkat) and probably that date is a valid Date object.

If you do this, you also have to consider not modifying the date parameter and copy it instead.

The names on the variables are clear enough, but not of the function, dates is too broad. getNextDayOfWeek says a lot about what this function does.

function getNextDayOfWeek(date, dayOfWeek)

The logic is correct, I think, I only tested it with a few numbers. But you instead of + ((-1) * diff)) you could simply do - diff.

Finally, you're always outputting the result to the console. If this is more than an exercise, you should return the result, and let the user of the function do with it whatever he/she needs.

Edit: As SridharVenkat said, the range should be 0-6 not 1-7.

Also, using modulo like AlexAtNet suggested you can reduce the code with resultDate.setDate(date.getDate() + (7 + dayOfWeek - date.getDay()) % 7)

My (edited) proposal:

function getNextDayOfWeek(date, dayOfWeek) {
    // Code to check that date and dayOfWeek are valid left as an exercise ;)

    var resultDate = new Date(date.getTime());

    resultDate.setDate(date.getDate() + (7 + dayOfWeek - date.getDay()) % 7);

    return resultDate;
}

PS: Please correct me if I said something wrong of if there's more to improve.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ i don't have 15 points to upvote. once i get i will do that. In dayOfWeek parameter it should be 0-6, that's how javascript works. \ \$\endgroup\$ Oct 31, 2013 at 8:45
  • \$\begingroup\$ Corrected, and also used @AlexAtNet version without the ifs \$\endgroup\$
    – Pablo
    Oct 31, 2013 at 14:54
  • \$\begingroup\$ If you wanting the next Friday when you're on a Friday so not the current Friday you need to change it slightly (date.getDate() + (7 + dayOfWeek - date.getDay()+1) % 7) +1 this will make your modulo work from tomorrow so it will zero out unless your on a Friday and leave a +1 if your are. \$\endgroup\$ Mar 10, 2016 at 14:38
  • \$\begingroup\$ @Pablo this will return the next day, not the wanted day, instead I found this to work for me: return resultDate.setDate(date.getDate() + (((7 + dayOfWeek - date.getDay()) % 7) || 7)) \$\endgroup\$
    – benomatis
    May 9 at 21:41
6
\$\begingroup\$

You can produce a formula by looking at the values that you have and the values that you want.

You have the current day of week, and you want to know how many days to go forward to get to a friday:

day offset
--- ------
 0    +5
 1    +4
 2    +3
 3    +2
 4    +1
 5    +0
 6    +6

You can use 5 - dayOfWeek to get the right value for most days:

day offset 5-d
--- ------ ---
 0    +5    5
 1    +4    4
 2    +3    3
 3    +2    2
 4    +1    1
 5    +0    0
 6    +6   -1

You could just add 7 when you get a negative value and you would be there, but you can also use %7 to get there. Add another week so that you have all positive values, then use % to get it down to the range 0-6:

day offset 5-d 12-d (12-d)%7
--- ------ --- ---- --------
 0    +5    5   12      5
 1    +4    4   11      4
 2    +3    3   10      3
 3    +2    2    9      2
 4    +1    1    8      1
 5    +0    0    7      0
 6    +6   -1    6      6

So the formula for the offset would be (dayOfWeek + 7 - currDayOfWeek) % 7. Using getDate and setDate to change a date:

function dates() {
  var dayOfWeek = 5;//friday
  var date = new Date(2013, 10, 13);
  date.setDate(date.getDate() + (dayOfWeek + 7 - date.getDay()) % 7);
  console.log(date);
}

And in a more reusable form:

function setDay(date, dayOfWeek) {
  date = new Date(date.getTime ());
  date.setDate(date.getDate() + (dayOfWeek + 7 - date.getDay()) % 7));
  return date;
}
\$\endgroup\$
3
  • \$\begingroup\$ Thanks for the explanation... It helped a lot. Few issues i found. 1) 'GetDate' should be 'getDate'. 2) setDate does not return a date rather a number(time), so we have to get rid of the getTime there.. updated code here -jsfiddle.net/aS5sh \$\endgroup\$ Nov 3, 2013 at 4:51
  • \$\begingroup\$ @SridharVenkat: Thanks. I updated the code so that it doesn't use the return value of the setDate method at all, as that is undocumented. \$\endgroup\$
    – Guffa
    Nov 3, 2013 at 6:39
  • \$\begingroup\$ Please check @Remy Mellet answer that has small improvement if you want a next week's date of today. \$\endgroup\$
    – iaforek
    Jun 11, 2018 at 6:40
5
\$\begingroup\$

In my case I don't want to have the current day if the day I'm asking is today. Improved solution of previous answer :

    /**
     * Returns the date of the next day. If today is friday and we are asking for next friday the friday of the next week is returned.
     * @param dayOfWeek 0:Su,1:Mo,2:Tu,3:We,4:Th,5:Fr,6:Sa
     */
    getNextDayOfWeek: function(date, dayOfWeek) {
        var resultDate = new Date(date.getTime());
        resultDate.setDate(date.getDate() + (7 + dayOfWeek - date.getDay() - 1) % 7 +1);
        return resultDate;
    },
\$\endgroup\$
0
\$\begingroup\$
  1. No, it looks fine.
  2. Yes, it can be. A hint: use "% 7" - this will narrow the delta to the one week only.
\$\endgroup\$
3
  • \$\begingroup\$ Alex, date.getDay() is already Mod 7. I don;t know how %7 can improve \$\endgroup\$ Oct 31, 2013 at 8:41
  • \$\begingroup\$ d.setDate(d.getDate() + (12 - d.getDay()) % 7); will set the d to the next Friday. \$\endgroup\$ Oct 31, 2013 at 11:33
  • 1
    \$\begingroup\$ @AlexNetkachov Interesting solution with 12. Can you add a bit more explanation, please? \$\endgroup\$
    – iaforek
    Jun 11, 2018 at 6:42

Not the answer you're looking for? Browse other questions tagged or ask your own question.