DEV Community

Cover image for Scheduling Tools for Teams Across Different Time Zones

Posted on • Updated on

Scheduling Tools for Teams Across Different Time Zones

Scheduling appointments and booking meetings can sometimes be a huge struggle. It's fairly easy to book 1-on-1 appointments with tools synced to our personal and work calendars. But what about scheduling meetings with multiple attendants or large groups? To make matters worse, what if it's an international team spread across different time zones.

In this post I will introduce and explain one of the solutions we built at Spurwing to facilitate group availability calendars and team scheduling.


This solution is built with JavaScript and NodeJS v12+. We utilized the following libraries: jQuery, Luxon and Express.


Live demo link:

group scheduling tool demo
The calendar is used to select a few candidate dates (no limit). Upon submitting you will see two links appear, one for the results page and one to share with others for submissions.

User submission page:
group scheduling tool demo
On the submission page each user can click the cells to indicate their availability for a given date and time. A name and email address must be provided in order to submit the answer. Updating an already submitted answer is possible by re-submitting using the same email.

Results page:
group scheduling tool demo
The results page shows the strict overlap of all the submissions of each user. Given these overlapping regions the host/organizer can proceed setting up a meeting at a date and time that fits everyone's calendar.

Notice that all data is time zone relative. This means that we can easily schedule and book meetings with members from different time zones on the fly. Each user's time zone is taken into account and translated into a universal UTC timestamp. The final results page shows all submissions relative to the viewer's time zone.

Coming soon: the ability to schedule the meeting using Spurwing's API and send email invitations to all participants.


The full implementation of this group scheduling solution is available on our Github sub-repository. The root directory of our repository will include several more related solutions.


The server.js script represents a NodeJS API/REST server running on port 8000 by default. It has several endpoints for obtaining, submitting and updating data. A JSON file-based database is used for demo purposes, it's recommended to replace this with a production-ready database such as MongoDB.


The public directory contains the HTML, JavaScript and CSS files. All custom JavaScript code is located inside the HTML files for demo purposes. The scheduler JS and CSS files are external and open-source resources for the UI scheduler.

Our custom JavaScript code is pretty short and simple. The only complexity that is unavoidable is due to the UI scheduling library. It uses rows and columns as indicators for the cells. There is no internal association between cells and actual date/time data. This information is implicit and computed based on the rows and columns given the accuracy (i.e. precision) of the 24 hour period.


It may be interesting to explain how this conversion between row:col to datetime is achieved.

Inside meeting.html we have some custom JavaScript code that is responsible for: capturing the user's selection, translating the selection data into an ISO datetime format, then to an UTC equivalent and finally send the data to the server:

let selection = [];
const accuracy = 2; // 30 minute intervals
let dates = [...]; // date strings associated with the meeting

  accuracy: accuracy,
  onSelect: (x) => convert(x, dates),
            // x contains all selected cells in the format:
            // { row1: [...cols], row2: [...cols] }
            // the row keys are just numbers starting from 1.
            // the value is an array of columns starting from 0.

// convert row-column format into ISO/UTC date format
function convert(sel, dates) {
  selection = []; // empty previous selection (if any)
  for (const row_ in sel) {
    for (const col of sel[row_]) {
      let row = row_ - 1; // make row zero-based
      let hour = Math.floor(col/accuracy) // compute hour
      let minute = ((col / accuracy) - hour)*60; // compute minutes
      let dt = luxon.DateTime.fromISO(dates[row]); // get date and parse it
      dt.set({hour, minute}); // set hour and minutes
      selection.push(dt.toUTC().toString()) // relative to UTC datetime

// on click submit -> send { selection } as data
Enter fullscreen mode Exit fullscreen mode

A similar reverse operation is carried out in results.html, where the UTC datetimes are obtained from the server, strictly overlapped, converted to the user's detected time zone and finally displayed on the read-only UI.


You can host this piece of software on your server or a cloud provider and use it. But you may also want to add an additional security layer (e.g. password) to help prevent users from brute forcing the meeting ID to view/collect names and emails of all users.

In the end this solution saves us a ton of time in scheduling meetings, especially in international teams across multiple time zones. For more tools and resources visit our Github page.

Discussion (0)