Javascript IF/ELSE - Shorten function

Viewed 127

I am playing around with the JavaScript IF/ELSE to understand better how it works. As an exercise I took the following working hours of a shop:

  • 6AM to 6PM = Open
  • 6PM to 6AM = Closed

then I created a function that returns the word 'Open' or 'Closed' based on the 2 values "time" and "period".

function shopHours(time,period) {
if (time === 6 && period === 'AM') {
return 'Open';
} else if (time === 6 && period === 'AM') {
return 'Open';
} else if (time === 7 && period === 'AM') {
return 'Open';
} else if (time === 8 && period === 'AM') {
return 'Open';
} else if (time === 9 && period === 'AM') {
return 'Open';
} else if (time === 10 && period === 'AM') {
return 'Open';
} else if (time === 11 && period === 'AM') {
return 'Open';
} else if (time === 12 && period === 'PM') {
return 'Open';
} else if (time === 1 && period === 'PM') {
return 'Open';
} else if (time === 2 && period === 'PM') {
return 'Open';
} else if (time === 3 && period === 'PM') {
return 'Open';
} else if (time === 4 && period === 'PM') {
return 'Open';
} else if (time === 5 && period === 'PM') {
return 'Open';
} else {
return 'Closed';} 
}

Everything works fine. However, I would like to be able to shorten the code as it looks too confusing.

I then tried the following:

function shopHours(time,period) {
if(time <= 6 && period === 'AM') {
return 'Closed';
} else if (time >= 6 && period === 'PM') {
return 'Closed';
} else if (time === 12 && period === 'PM') {
return 'Open';
} else {
return 'Open';}
}

The second code works fine too and is much shorter however there is a problem that I am not sure how to solve. When the time and period are set to 12 and PM, the result should be 'closed' but I am not sure how to implement this.

I have tried to add the following code but it seems that would not solve this problem.

 else if (time === 12 && period === 'AM') {
return 'Closed';
}

I will be very grateful to anyone that will spend a bit of his time to take a look at this question.

Thank you!

5 Answers

You can break it down into two initial scenarios, either AM or PM. Then check the hour to see if it should be open or closed.

if (period == "AM") {
    if (time < 6 || time == 12) 
        return "Closed";
    return "Open";
}
else {
    if (time >= 6 && time != 12)
        return "Closed";
    return "Open";
}

It's easier to work with 24-hour format, in my opinion. One has to take 12PM = 12:00 and 12AM = 00:00 into account however.

After conversion the comparision is fairly easy.

function shopHours(time, period) {
    let hour = time;
    if (period === 'PM' && hour < 12) hour = hour + 12;
    if (period === 'AM' && hour === 12) hour = hour - 12;

    if (hour >= 6 && hour < 18) {
        return 'Open';
    }

    return 'Closed';
}

console.log('12 AM is ' + shopHours(12, 'AM') + '. Expected it to be: Closed');
console.log('3 AM is ' + shopHours(3, 'AM') + '. Expected it to be: Closed');
console.log('6 AM is ' + shopHours(6, 'AM') + '. Expected it to be: Open');
console.log('9 AM is ' + shopHours(9, 'AM') + '. Expected it to be: Open');
console.log('12 PM is ' + shopHours(12, 'PM') + '. Expected it to be: Open');
console.log('3 PM is ' + shopHours(3, 'PM') + '. Expected it to be: Open');
console.log('6 PM is ' + shopHours(6, 'PM') + '. Expected it to be: Closed');
console.log('9 PM is ' + shopHours(9, 'PM') + '. Expected it to be: Closed');

My version.if goal is to just shorten the code, then those am() and pm() functions can be omitted and the code inside can be added where am calling them. That would be 3 lines of code.

function shopHours(time, period){
var result;
function am () {
  Number(time) < 12 && Number(time) >= 6 ? result = "open" : result = "closed";
}
function pm() {
    Number(time) <= 5 || Number(time) === 12 ? result = "open" : result = "closed";
}
period === 'AM' ? am() : pm();

return result;
}

console.log("12 AM is: ", shopHours(12, 'AM'), '; expected: closed');
console.log("3 AM is: ", shopHours(3, 'AM'), '; expected: closed');
console.log("6 AM is: ", shopHours(6, 'AM'), '; expected: open');
console.log("9 AM is: ", shopHours(9, 'AM'), '; expected: open');
console.log("12 PM is: ", shopHours(12, 'PM'), '; expected: open');
console.log("3 PM is: ", shopHours(3, 'PM'), '; expected: open');
console.log("6 PM is: ", shopHours(6, 'PM'), '; expected: closed');
console.log("9 PM is: ", shopHours(9, 'PM'), '; expected: closed');

This can be easily handled using date instead. Instead of using if else, You can define the openHours and closeHours. And pass the current time. You can easily compare then.

Sample:

function shopHours(time, period) {
  let openHour = new Date();
  let closeHour = new Date();
  openHour.setHours(6);
  closeHour.setHours(12 + 6);

  let curreTime = new Date();
  curreTime.setHours(period === "PM" ? 12 + time : time);
  if (curreTime > openHour && curreTime < closeHour) return "Open";
  return "Close";
}

console.log(shopHours(11, "PM"));
console.log(shopHours(12, "AM"));
console.log(shopHours(11, "AM"));
console.log(shopHours(7, "AM"));
console.log(shopHours(5, "AM"));

You can also just pass the currentTime and validate.

function shopHours(curreTime) {
  let openHour = new Date();
  let closeHour = new Date();
  openHour.setHours(6);
  closeHour.setHours(12 + 6);
  if (curreTime > openHour && curreTime < closeHour) return "Open";
  return "Close";
}

console.log(shopHours(new Date()));

My suggestion:

function shopHours(time, period) {
  var status = "Open";
  if ((period == "AM" && (time < 6 || time == 12)) || (time >= 6 && time != 12)) status = "Closed";
  return status;
}

console.log(shopHours(5, "AM"));
console.log(shopHours(5, "PM"));

Related