App upgraded

Microsoft Outlook: Calendar → Scheduling Assistant. The new feature, Fairshift, adds a Rotate time fairly option for recurring meetings.

The problem

Global teams book recurring meetings at a time that suits headquarters, so the same people (often in India or APAC) join at 10 PM or 6 AM every week, for months. Outlook's Scheduling Assistant shows free/busy in the organizer's time zone. For a recurring series, nothing tracks who keeps absorbing the inconvenience, and nothing shares it.

Before → After

Before (Outlook today): Maya in San Francisco books a weekly sync at 9:00 AM PT. Everyone shows as free. Nothing tells her it's 10:30 PM for Priya in Bengaluru, 26 weeks in a row.

Before: Outlook today

After (with Fairshift): Every row is painted in that person's own local time, and Fairshift shows that Priya carries 87% of the team's after-hours load (fairness 37). With one switch, the series alternates between 6:30 and 7:30 AM PT. Fairness rises to 97, Priya's load drops 61% (about 42 late nights a year back), and nobody is ever scheduled in their sleep hours.

After: Fairshift fair rotation

Inspiration

I'm in India, and for many people here "the global sync" means a 10:30 PM call every week. Nobody chose that on purpose. The organizer picked a sensible time in their own zone, the Scheduling Assistant showed everyone as free, and the series repeats forever. Outlook already knows everyone's time zone and working hours; it just never does the maths across the whole series.

What it does

  • Local-time lens: each attendee's row is coloured by their own local time (work, edge, evening, late, sleep, weekend), including date-line weekends: Friday afternoon in the US is Saturday in Sydney.
  • Burden and fairness scores for the whole recurring series, per person.
  • Rotate time fairly: one switch plans a series that rotates between up to 3 times, so the after-hours load is shared.
  • Protect sleep: nobody is ever booked between 11 PM and 6 AM.
  • Fairness ledger: remembers late calls people already take in other meetings, and spares them.
  • Early bird / night owl preferences: a 7 AM call costs an early bird less than a 9 PM one.
  • Best single time: if you don't want a rotating series, Fairshift still suggests the fairest fixed time.
  • DST-aware: the US, UK and India change clocks on different dates, so every occurrence is re-scored.
  • Self-explaining invite listing each attendee's local time, a before/after toggle, and a 9-step guided demo.

How I built it

A dependency-free JavaScript engine converts every candidate time into each attendee's wall-clock time with the browser's Intl time-zone database, per occurrence, in 15-minute slices. Each attendee's burden over the series is:

$$B_i = \sum_{\text{meetings}} \; \sum_{\text{15-min slices}} w(\text{local time}) \cdot \Delta t$$

where the weight per hour is 0 in working hours, 1 just outside them, 2 in the evening or early morning, 4 late at night or at weekends, and 10 during sleep hours.

The planner tests every half-hour of the day, keeps only the Pareto-optimal times, tries every rotation of 1–3 times, and assigns each meeting so as to minimise

$$J = \max_i B_i + 0.35 \sum_i B_i$$

This is minimax: it protects the person carrying the most first, then reduces total after-hours time. The fairness score compares the heaviest load with the best this planet allows:

$$\text{Fairness} = 100 \cdot \frac{B^\star}{\max_i B_i}, \qquad B^\star = \min_{\text{rotations}} \max_i B_i$$

The full search takes about 10 ms in the browser. The UI is a Fluent-inspired recreation of Outlook's event composer and Scheduling Assistant in vanilla HTML, CSS and JavaScript, with 8 engine tests on Node's built-in test runner.

The demo video is generated by a script: it drives the real app in headless Chrome over the DevTools protocol, the voiceover comes from the open-source Kokoro-82M TTS model, and ffmpeg combines them. I built the project with Claude Code (Claude Opus 5.5) as my AI pair-programmer.

Challenges I ran into

  • Defining "fair". Pure equality (Gini) would inconvenience the person in the middle time zone for no benefit to anyone. I switched to minimax and measured fairness against the best achievable schedule, because some burden is unavoidable given where people live.
  • Time zones. DST changes on different dates, India's half-hour offset and the date line meant every occurrence had to be computed individually. A fixed offset table would have been quietly wrong half the year.

Accomplishments that I'm proud of

  • Fairness 37 → 97 for a US/UK/India team, and 34 → 96 for a four-city follow-the-sun team with the ledger on.
  • Zero sleep-hour meetings, with the organizer sharing the early starts.
  • It uses only data Exchange already has, so it could really ship.

What I learned

Time-zone fairness is a problem across the whole series, not a single meeting. Once people can see their burden next to everyone else's, the conversation becomes easy.

How Outlook could ship it

Everything Fairshift needs is already in Microsoft Graph:

  • mailboxSettings.workingHours for each attendee's time zone and working hours
  • getSchedule / findMeetingTimes for free/busy
  • recurring events with modified occurrences, which can store a rotating series

Rollout would be in three steps:

  1. Ship the local-time lens as a read-only overlay.
  2. Add Rotate time fairly as an opt-in toggle in Targeted Release.
  3. Connect the fairness ledger to Viva Insights' after-hours data, visible only to the organizer and each attendee.

Unofficial concept prototype. Not affiliated with or endorsed by Microsoft. All people shown are fictional.

Built With

Share this project:

Updates

Submission history