0

I'm supposed to write a code for codewars to find out the number of times a month ends with a Friday within a range of years.

To start off, I did research and found out several solutions but I still couldn't figure out the results in the console.log.

The first solution is from this tutorial: In this code, the solution is

let LastDay = new Date(1998, 5 + 1, 0).getDate();

I was able to get the date, but it wasn't clear which day the date falls upon.

Then I found another solution at w3schools. This solution also set the date to be the last day of this month:

var d = new Date();
d.setMonth(d.getMonth() +1, 0);
document.getElementById("demo").innerHTML = d;

However, it works if it displays it as innerHTML = Sat Nov 30 2019 00:57:09 GMT-0500 (Eastern Standard Time). However, when I tried to rewrite the code and console.log it like in this example:

let d = new Date();
  let month = d.getMonth()+1;
let lastday = d.setMonth(month, 0);
  console.log(lastday);

The result I got was 1575093343211. I don't understand how it displays those numbers instead of the dates I was expecting. I thought that if it does display the dates, starting with the day, I can convert the date to string or array and check if the first element is Friday and then add it to the counter in the code I'm writing. How do I get the code to display the way I want it to.

Kristina Bressler
  • 1,642
  • 1
  • 25
  • 60
  • 2
    Check out [`Date.getDay()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDay) – Nick Nov 10 '19 at 06:11

5 Answers5

1

something like this will work...

function LastDayOfMonth(Year, Month) {
  return new Date((new Date(Year, Month, 1)) - 1);
}

var d = LastDayOfMonth(new Date().getYear(), new Date().getMonth())
//var d = LastDayOfMonth(2009, 11)

var dayName = d.toString().split(' ')[0];
console.log(dayName)
roottraveller
  • 7,942
  • 7
  • 60
  • 65
  • `let d = new Date(); let month = d.getMonth()+1; let lastday = d.setMonth(month, 0).toString().split(' ')[0]; console.log(lastday);` isn't working. this code was supposed to display the last day of current month. – Kristina Bressler Nov 10 '19 at 06:20
  • err....that code you wrote might have displayed the wrong month and year. It's displaying Oct 31 0119 on Tuesday. I changed `getYear()` to `getFullYear()`. Anyway, with `getFullYear()` It's still displaying last month... – Kristina Bressler Nov 10 '19 at 06:52
1

The result I got was 1575093343211. I don't understand how it displays those numbers instead of the dates I was expecting

Because you console.log the output of the setMonth method, not the date object:

let lastday = d.setMonth(month, 0);
console.log(lastday);

According to the documentation, the setMonth method returns:

The number of milliseconds between 1 January 1970 00:00:00 UTC and the updated date.

Instead you should use that output to create a new instance of the date object:

let lastday = new Date(d.setMonth(month, 0));
console.log(lastday);
Mike Doe
  • 16,349
  • 11
  • 65
  • 88
  • I ran the code you recommended and the result I got is `[object Date] {}` – Kristina Bressler Nov 10 '19 at 07:09
  • I didn't mean to do this for you, but explained instead what the problem is as you asked (vide `I don't understand how it displays those numbers`). You have to show [some effort](https://www.google.com/search?q=js+date+check+what's+the+day). You already have the date object. From now on all you have to do is check it's friday or not. It's a matter of a single if statement. One doesn't learn from getting a solution from somebody else… – Mike Doe Nov 10 '19 at 10:11
  • Thanks for letting me know about the numbers and I just got the results I expected when I added .toString to `d` in console.log(d). I'm now going to write the code to find numbers of months within a range of years. – Kristina Bressler Nov 10 '19 at 21:27
1

Algorithms to get the last day of the month are generally based on setting a date to day 0 of the following month, which ends up being the last day of the required month.

E.g. to get the last day for June, 2019 (noting that 6 is July, not June):

let endOfJune = new Date(2019, 6, 0):

Once you have the date, you can get the day where 0 is Sunday, 1 is Monday, etc. and 5 is Friday:

let endOfJuneDay = endOfJune.getDay();

The set* methods modify the Date they're called on and return the time value for the modified date. So you don't need to assign the result to anything:

let d = new Date();
let month = d.getMonth() + 1;
// Set date to the new month
d.setMonth(month, 0);
console.log(d);

So if you want to loop over the months for a range of years and get the number that end with a Friday (or any particular day), you might loop over the months something like:

/*
** @param {number} startYear - start year of range
** @param {number} endYear   - end year of range
** @param {number} dat       - day number, 0 = Sunday, 1 = Monday, etc.
**                             default is 0 (Sunday)
*/
function countEOMDay(startYear, endYear, day = 0) {
  // startYear must be <= end year
  if (startYear > endYear) return;
  
  // Start on 31 Jan of start year
  let start = new Date(startYear, 0, 31);
  
  // End on 31 Dec of end year
  let end = new Date(endYear, 11, 31);
  let count = 0;
  
  // Loop over months from start to end
  while (start <= end) {
    // Count matching days
    if (start.getDay() == day) {
      ++count;
    }
    // Increment month to end of next month
    start.setMonth(start.getMonth() + 2, 0);
  }
  return count;
}

console.log(countEOMDay(2019, 2019, 5)); // 1
console.log(countEOMDay(2018, 2019, 5)); // 3
RobG
  • 142,382
  • 31
  • 172
  • 209
1

You can use setMonth() method to set the month of a date object. The return value of setMonth() method is milliseconds between the date object and midnight January 1 1970. That's what you get from console.log(lastday);

Your return value,

1575093343211

is milliseconds between your date object (d) and midnight January 1 1970.

If you want to get the expected date, you have to console log your date object instead the lastday, as follows:

  let d = new Date();
  let month = d.getMonth()+1;
  let lastday = d.setMonth(month, 0);
  console.log(d);

output: Sat Nov 30 2019 00:02:47 GMT+0530 (India Standard Time)

This is an alternative solution I wrote to solve your problem. This will return the number of times a month ends with a Friday within a range of years. Hope this will help you :)

var days = [];
var count = 0;

    function getLastFridaysCount(startYear, endYear) {

          for (var year = startYear; year <= endYear; year++) {

            days = [
                31,
                0 === year % 4 && 0 !== year % 100 || 0 === year % 400 ? 29 : 28,
                31, 30, 31, 30, 31, 31, 30, 31, 30, 31
            ];

            for (var month = 0; month <= 11; month++) {
              var myDate = new Date();
              myDate.setFullYear(year);
              myDate.setMonth(month);
              myDate.setDate(days[month]);

              if(myDate.getDay() == 5)
              {
                count++;
              }

      } 
          }

        return count;
    }

    console.log("count", getLastFridaysCount(2014, 2017));
Thilina Koggalage
  • 1,044
  • 8
  • 16
0

this is the solution, in the code can find the comments "//" explaining of what happens in each iteration.

function lastDayIsFriday(initialYear, endYear) {
  let count = 0;
  //according to when the year ends starts the loop
  if (endYear !== undefined) {
    
    let start = new Date(initialYear, 0, 31);
    let end = new Date(endYear, 11, 31);
    
    while(start <= end) { //check if the start date is < or = to the end
      //The getDay() method returns the day of the week (from 0 to 6) for the specified date.
      if(start.getDay() === 5) { //if = to FriYAY!!!
        count++; //count the day
      }
      start.setMonth(start.getMonth()+2, 0);// returns the month (from 0 to 11) .getMonth
    }                                      //& sets the month of a date object  .setMonth
    return count;
  } else {
    let start = new Date(initialYear, 0, 31);
    console.log(start.toString());
    for(let i = 0; i < 12; i++) {
      if(start.getDay() === 5) {
        count++;
      }
      start.setMonth(start.getMonth() + 2, 0);
      // console.log(start.toString());
    }
    return count;
  }
  }
Stefano
  • 63
  • 6
  • Welcome to StackOverflow. While this code may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply. Have a look here → [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer) – Federico Baù Jan 26 '21 at 09:30