A time-driven trigger that fires at 3am and emails a client is a support ticket waiting to happen. isWithinBusinessHours(startHHmm, endHHmm, opts) tells you whether now (or a given Date) falls inside a window like 09:00–17:00 on weekdays, using the spreadsheet’s timezone when one is available (falling back to the script timezone).
When to use
- Skip / defer outbound emails and Slack pings outside office hours
- Gate a menu action that should only run during the day
- Soft “are we open?” checks before kicking off a long sync
How to use this snippet
/**
* Return true if `when` (default: now) falls inside [startHHmm, endHHmm)
* on an allowed weekday, evaluated in the spreadsheet timezone
* (falls back to Session.getScriptTimeZone()).
*
* @param {string} startHHmm e.g. '09:00'
* @param {string} endHHmm e.g. '17:00' (exclusive)
* @param {{when?: Date,
* weekdays?: number[],
* spreadsheet?: GoogleAppsScript.Spreadsheet.Spreadsheet}=} opts
* weekdays 1=Mon … 7=Sun (ISO). Default Mon–Fri.
* @return {boolean}
*/
function isWithinBusinessHours(startHHmm, endHHmm, opts) {
opts = opts || {};
var ss = opts.spreadsheet
|| (typeof SpreadsheetApp !== 'undefined' ? SpreadsheetApp.getActive() : null);
var tz = (ss && ss.getSpreadsheetTimeZone && ss.getSpreadsheetTimeZone())
|| Session.getScriptTimeZone()
|| 'America/New_York';
var when = opts.when || new Date();
// 'u' = ISO weekday 1–7 in that timezone
var weekday = Number(Utilities.formatDate(when, tz, 'u'));
var allowed = opts.weekdays || [1, 2, 3, 4, 5];
if (allowed.indexOf(weekday) === -1) return false;
var toMins = function (hhmm) {
var parts = String(hhmm).split(':');
return Number(parts[0]) * 60 + Number(parts[1] || 0);
};
var nowMins = Number(Utilities.formatDate(when, tz, 'H')) * 60
+ Number(Utilities.formatDate(when, tz, 'm'));
var start = toMins(startHHmm);
var end = toMins(endHHmm);
// Half-open [start, end) so exactly 17:00 is "closed"
if (end <= start) {
// Overnight window, e.g. 22:00 → 06:00
return nowMins >= start || nowMins < end;
}
return nowMins >= start && nowMins < end;
}
Example
function sendClientDigestIfOpen() {
if (!isWithinBusinessHours('09:00', '17:00')) {
console.log('Outside business hours — skipping send');
return;
}
sendClientDigest_();
}
// Include Saturday; run as a standalone script against a known spreadsheet
function weekendSupportWindow() {
var ss = SpreadsheetApp.openById(PropertiesService.getScriptProperties().getProperty('opsSsId'));
return isWithinBusinessHours('10:00', '14:00', {
spreadsheet: ss,
weekdays: [1, 2, 3, 4, 5, 6]
});
}
Tips:
- Always prefer the spreadsheet timezone for anything ops sees in that file — the script project’s zone can drift. See the timezone guide if you’ve been burned before.
- The end time is exclusive (
[09:00, 17:00)). At exactly 17:00 the function returns false. - Overnight windows (
22:00→06:00) are supported:end <= startflips the comparison. - This is a gate, not a scheduler — pair it with a time-driven trigger that fires often enough, or with a “defer until open” queue.
Tip: NitroGAS Co-Pilot can wrap an existing send function in an isWithinBusinessHours check if you paste it and say “only Mon–Fri 9–5 in the sheet’s timezone.”
Happy Coding!
