Disclosure: I make an iOS sleep app (linked at the end). The code below is free to use and does not need it.

A lot of "sleep calculators" boil down to one idea: sleep comes in cycles of roughly 90 minutes, so count backwards from your alarm in whole cycles. That's a rough model, not a medical fact, because real cycles vary between people and across the night. But it is a handy rule of thumb, and it takes about 15 lines of JavaScript.

The code

// Bedtime calculator: count back whole 90-minute cycles from a wake time. const CYCLE = 90; // minutes, an average, not a constant const FALL_ASLEEP = 15; // minutes, a typical assumption function bedtimes(wake, cycles = [6, 5, 4]) { const [h, m] = wake.split(":").map(Number); const wakeMin = h * 60 + m; return cycles.map((c) => { const t = (((wakeMin - c * CYCLE - FALL_ASLEEP) % 1440) + 1440) % 1440; const hh = String(Math.floor(t / 60)).padStart(2, "0"); const mm = String(t % 60).padStart(2, "0"); return { cycles: c, sleepHours: (c * CYCLE) / 60, bedtime: `${hh}:${mm}` }; }); } console.log(bedtimes("06:30")); 

Running it for a 06:30 alarm (I ran this with Node before posting):

[ { cycles: 6, sleepHours: 9, bedtime: '21:15' }, { cycles: 5, sleepHours: 7.5, bedtime: '22:45' }, { cycles: 4, sleepHours: 6, bedtime: '00:15' } ] 

Two details that bite

  1. Wrap past midnight. (x % 1440 + 1440) % 1440 keeps the result in 0 to 1439 even when the subtraction goes negative. Without the double modulo, JavaScript returns negative remainders and you print times like -45:00.
  2. The fall-asleep buffer. The 15 minutes is an assumption. If you take longer to drop off, the "cycle-aligned" result is already off before you start. Treat the output as a target to head to bed, not as a guarantee of how you will wake.

Where this model stops

  • The 90-minute figure is an average. Individual cycles run shorter or longer.
  • It says nothing about regularity. Going to bed and waking at the same time most days usually matters more than hitting an exact cycle boundary.
  • If you have persistent insomnia or daytime sleepiness, a calculator is not a substitute for talking to a clinician.

Where to take it

Easy extensions: read the wake time from an <input type="time">, show the next three alarms for a given bedtime instead, or let the user set their own cycle length and buffer.

If you would rather not build it yourself: I make Sleep Reset for iPhone. It has a free sleep reset score; the personalized plan and bedtime timing need a paid subscription.