FreeCodeCamp and JavaScript: Friendly Date Ranges

For me, this is the last challenge in the Front End Certificate.  I started this back when the list was a LOT shorter, and I had already completed the final three challenges.  I may end up writing them up as blog posts if I get time, and if I get any requests…

For now, though, let’s take a look at this challenge on dates!

Here’s the assignment:

“Convert a date range consisting of two dates formatted as YYYY-MM-DD into a more readable format.

The friendly display should use month names instead of numbers and ordinal dates instead of cardinal (1st instead of 1).

Do not display information that is redundant or that can be inferred by the user: if the date range ends in less than a year from when it begins, do not display the ending year.

Additionally, if the date range begins in the current year and ends within one year, the year should not be displayed at the beginning of the friendly range.

If the range ends in the same month that it begins, do not display the ending year or month.

Examples:

makeFriendlyDates([“2016-07-01”, “2016-07-04”]) should return [“July 1st”,”4th”]

makeFriendlyDates([“2016-07-01”, “2018-07-04”]) should return [“July 1st, 2016”, “July 4th, 2018″].”

The hints:

And here’s the starter code:

function makeFriendlyDates(arr) {
  return arr;
}

makeFriendlyDates([‘2016-07-01’, ‘2016-07-04’]);

So, I started by getting the data I needed into variables.  We’ll always get two dates; they are in an array.  The first date can be split into three items using a dash separator (‘-‘), as can the second.  I added each of those to a new array, which now has two subarrays.  I can get the year, which is always the first item in each array (So, [0][0] and [0][1]).  I can get the month, the second item, and the day, the third item.

I then created two “helper” functions, which are not IN the makeFriendlyDates() function – they are standalone.  The first, getMonth, uses a switch function to assign a month to the number sent from the second values in the arrays.  The other, get date, uses a bunch of if…then statements to convert the number of the day to an ordinal value – so, 01 becomes 1st, o2 becomes 2nd, 17 becomes 17th, and so on.

So, I thought, now I was all set.  I knew the year, so I could just throw together a couple of if…then statements based on what the dates were and I was good to go right?

As always, not right.

Most of it WAS easy – the base case, returning all the years, months, and days, was easy, as was the case where the years were the same, the year and month the same, and the day, month AND year the same.

But then there were two cases that weren’t working – when they were in different years, and less than /more than 365 days.  I could get one or the other to work but not both at the same time.  I was baffled.  So I did some research on the Date() method.

You can’t just subtract 365 to get the days in between, of course, and so I had to find a way to figure the amount of days in between the dates.  You can get that by sending the day, month and year to Date() and it will return the amount of time, in milliseconds(!) since January 1, 1970 (!!).  I have no idea who picked that date; I assume (and hope) there’s a reason for it.  In any case, that gives you the difference between the two dates in milliseconds which can be converted to days through a bit of math.

But it STILL wasn’t working for me.  And then I got it.

 

See, some of the dates were 2016…which is the current year.  So, the rule for that was a little different, and so I introduced a variable to get the current year.  If it was the current year, then the new rule applied….and that solved the last item!

 

My answer is below.  As always, ask questions if you have any, and I’ll be glad to answer them as best I can!

function makeFriendlyDates(arr) {
  var dates = [];
  var data = [];
  var thisYear = new Date().getFullYear();
  for (var item in arguments) {
    dates.push(arguments[item]);
  }
  var first = dates[0][0].split(‘-‘);
  data.push(first);
  var second = dates[0][1].split(‘-‘);
  data.push(second);
  var year1 = data[0][0];
  var year2 = data[1][0];
  var month1 = data[0][1];
  var month2 = data[1][1];
  var date1 = data[0][2];
  var date2 = data[1][2];
  var msPerDay = 1000 * 60 * 60 * 24;  // 1000ms/s * sec * min * hrs
  var calDate1 = new Date(year1, month1, date1);
  var calDate2 = new Date(year2, month2, date2);
  var diff = calDate2 – calDate1;
  var dateDiff = Math.round(diff/msPerDay);
  month1 = getMonth(month1);
  month2 = getMonth(month2);
  date1 = getDate(date1);
  date2 = getDate(date2);
  var firstDate;
  var secondDate;
  var answer = [];
  var yearOne = parseInt(year1);
  if(year1 === year2 && month1 === month2 && date1 === date2) {
    firstDate = month1 + ” ” + date1 + “, ” + year1;
    answer.push(firstDate);
  } else if (year1 === year2 && month1 === month2) {
    firstDate = month1 + ” ” + date1;
    secondDate = date2;
    answer.push(firstDate);
    answer.push(secondDate);
  } else if (year1 === year2) {
    firstDate = month1 + ” ” + date1 + “, ” + year1;
    secondDate = month2 + ” ” + date2;
    answer.push(firstDate);
    answer.push(secondDate);
  } else if(yearOne === thisYear && dateDiff < 365) {
    firstDate = month1 + ” ” + date1;
    secondDate = month2 + ” ” + date2;
    answer.push(firstDate);
    answer.push(secondDate);
  } else if(dateDiff < 365) {
    firstDate = month1 + ” ” + date1 + “, ” + year1;
    secondDate = month2 + ” ” + date2;
    answer.push(firstDate);
    answer.push(secondDate);
  } else {
    firstDate = month1 + ” ” + date1 + “, ” + year1;
    secondDate = month2 + ” ” + date2 + “, ” +  year2;
    answer.push(firstDate);
    answer.push(secondDate);
  }
  return answer;
}
function getMonth(month) {
  switch(month) {
    case ’01’:
      month = ‘January’;
      return month;
    case ’02’:
      month = ‘February’;
      return month;
    case ’03’:
      month = ‘March’;
      return month;
    case ’04’:
      month = ‘April’;
      return month;
    case ’05’:
      month = ‘May’;
      return month;
    case ’06’:
      month = ‘June’;
      return month;
    case ’07’:
      month = ‘July’;
      return month;
    case ’08’:
      month = ‘August’;
      return month;
    case ’09’:
      month = ‘September’;
      return month;
    case ’10’:
      month = ‘October’;
      return month;
    case ’11’:
      month = ‘November’;
      return month;
    case ’12’:
      month = ‘December’;
      return month;
  }
}
function getDate(date) {
  date = parseInt(date, 10);
  if(date === 1) {
    date = date + “st”;
  } else if (date === 2) {
    date = date + “nd”;
  } else if (date === 3) {
    date = date + “rd”;
  } else if (date >= 4 && date <= 20) {
    date = date + “th”;
  } else if (date === 21) {
    date = date + “st”;
  } else if (date === 22) {
    date = date + “nd”;
  } else if (date === 23) {
    date = date + “rd”;
  } else if (date >= 24 && date < 31) {
    date = date + “th”;
  } else if (date === 31) {
    date = date + “st”;
  }
  return date;
}
makeFriendlyDates([“2016-12-01”, “2017-02-03”]);
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s