Displaying Active Business Hours in JavaScript: Simple Script

blog image

Whether you’re managing a website for a local business or helpline, being able to display the operational hours or knowing if a business is currently open can be incredibly helpful.

In this blog post, we’ll guide you through creating a JavaScript function that can do just that. We will also be adding functionality to handle business exceptions like holidays and custom working hours.

This post is an adapted form of this gist by GitHub user KidGodZilla.

The Basic Setup

As we’re using Vanilla Javascript, the script below can be added to any page you’re hoping to display this information.

The basic idea here is to create a configuration object which maps each day of the week (from 0 for Sunday to 6 for Saturday) to its respective opening and closing times. Here is a basic example of what that could look like:

var config = {
  0: { open: 0, close: 0 },
  1: { open: 9, close: 17 },
  2: { open: 9, close: 17 },
  3: { open: 9, close: 17 },
  4: { open: 9, close: 17 },
  5: { open: 9, close: 17 },
  6: { open: 0, close: 0 },
  offset: -7 // PST (US)
};

In this configuration, the business operates from 9 AM to 5 PM (17:00 in 24-hour format), Monday to Friday. The business does not operate on Sundays (0) and Saturdays (6). The offset is set to -7 to represent Pacific Standard Time (PST) in relation to UTC.

Supporting Minutes

To support minute-specific opening and closing times, we convert the hours into a decimal format, where the fractional part represents the minutes. For example, 5:30 PM would be represented as 17.5.

Here’s how we would modify the configuration:

var config = {
  // ...
  1: { open: 9, close: 17.5 },
  // ...
  offset: -7
};

Adjusting for Timezones

To handle users in different timezones, we create a method that adjusts the given time to the business' local time using the timezone offset specified in the config.

Date.prototype.subHours = function (h) {    
   this.setTime(this.getTime() - (h * 60 * 60 * 1000));
   return this;   
}

This method subtracts the specified number of hours from the Date object it is called on.

Checking Business Hours

The isWorkingHour function checks if a given time falls within the business hours. We first adjust the given time to the business' local time, then check if it falls within the opening and closing times for the corresponding day of the week.

function isWorkingHour (now) {
  now = now.subHours(config.offset + (now.getTimezoneOffset() / 60));
  
  var day = now.getDay();
  var hours = now.getHours();
  var minutes = now.getMinutes();
  var currentTime = hours + minutes/60;

  return currentTime >= config[day].open && currentTime < config[day].close;
}

console.log(isWorkingHour(new Date())); // Check current time

Handling Exceptions

Businesses often have exceptions to their regular hours, such as holidays or special events. To handle this, we add an exceptions object to the config. Each key in this object is a date in YYYY-MM-DD format, and the value is the opening and closing times for that day.

var config = {
  // ...
  exceptions: {
    '2023-12-25': { open: 0, close: 0 }, // Christmas Day
    '2023-07-04': { open: 9, close: 13 }  // Independence Day
  }
};

We modify the isWorkingHour function to check the exceptions first.

function isWorkingHour (now) {
  // ...

  var dateString = now.getFullYear() + '-' + String(now.getMonth()+1).padStart(2, '0') + '-' + String(now.getDate()).padStart(2, '0');

  if (config.exceptions.hasOwnProperty(dateString)) {
    return currentTime >= config.exceptions[dateString].open && currentTime < config.exceptions[dateString].close;
  } else {
    return currentTime >= config[day].open && currentTime < config[day].close;
  }
}

And there you have it!

A complete function to determine whether a business is currently open, accounting for minute-specific times, timezones, and special exceptions.

You can adjust the configuration to match your business' specific schedule and timezone.

Limitations and Potential Enhancements

While the JavaScript function provided serves a specific use-case quite efficiently, it does have certain limitations that need to be considered:

  1. Multiple Working Sessions Per Day: Our script currently operates under the assumption that there is only one continuous working session per day. It doesn’t support businesses that may close and reopen within the same day (for example, a restaurant that’s open for lunch, closes in the afternoon, and then reopens for dinner).

  2. Type Checks for Values: The current script does not perform type checking for the values in the configuration object. Consequently, if a non-numeric value is accidentally inserted into the open or close times, the function may not perform as expected and could potentially fail.

  3. Invalid Time Range Checks: The script doesn’t check for invalid time ranges, such as if the closing time is earlier than the opening time. Providing such invalid ranges might lead to unexpected behavior or inaccurate results.

  4. Leap Year and Daylight Saving Time Adjustments: While our function adjusts for the timezone, it does not account for changes in time that occur due to leap years or daylight saving time. Additional adjustments would need to be added to cater to these scenarios.

  5. Handling of Exceptions for Non-Working Days: Our function will treat any day with an exception as a working day with the provided hours, even if it’s usually a non-working day (like Sunday). This may not be the intended behavior if, for example, you’re specifying public holidays that fall on these days.

  6. Multiple Exceptions for the Same Day: The script does not support multiple exceptions for the same day. If more than one exception is added for the same day, only the last one will be considered.

To make this function more robust, you might consider adding checks and validations to handle these scenarios. Alternatively, you could also expand its functionalities to better suit your specific business requirements.

Featured image generated using carbon.now.sh

Liked this story? Share it with someone who needs to see it 👇