Converts human-readable time into milliseconds. No more multiplying by 60 in your head when setting up setTimeout, setInterval, or rate limiters.
The interval function accepts optional days, hours, minutes, and seconds and returns the total milliseconds.
interface IntervalOptions {
hours?: number
minutes?: number
seconds?: number
days?: number
}
function interval({
hours = 0,
minutes = 0,
seconds = 0,
days = 0,
}: IntervalOptions): number {
return (((days * 24 + hours) * 60 + minutes) * 60 + seconds) * 1000
}Usage examples
Named constants read much better than magic numbers:
import { interval } from './milliseconds-interval-helper'
const FIVE_SECONDS = interval({ seconds: 5 })
const ONE_MINUTE = interval({ minutes: 1 })
const ONE_HOUR = interval({ hours: 1 })
const ONE_DAY = interval({ days: 1 })You can also combine units for mixed durations:
const SESSION_TIMEOUT = interval({ hours: 1, minutes: 30 })
const RETRY_DELAY = interval({ minutes: 2, seconds: 30 })In practice I use this most for setInterval polling and cache TTLs. Both of those tend to accumulate * 60 * 1000 chains that are easy to miscount:
// before
setInterval(syncData, 5 * 60 * 1000)
// after
setInterval(syncData, interval({ minutes: 5 }))Same result, but the intent is obvious on a quick read. When someone changes the polling frequency six months later they won’t need to reverse-engineer the arithmetic.
Rate limiting and debouncing
Works well as the delay argument for debounce or throttle utilities:
import { debounce } from 'lodash'
const saveDocument = debounce(save, interval({ seconds: 2 }))
const refreshToken = debounce(refresh, interval({ minutes: 15 }))Cache expiry
For anything that stores data with a TTL, this makes the expiry readable:
const cache = new Map<string, { data: unknown; expiresAt: number }>()
function set(key: string, data: unknown) {
cache.set(key, {
data,
expiresAt: Date.now() + interval({ minutes: 10 }),
})
}
function get(key: string) {
const entry = cache.get(key)
if (!entry || Date.now() > entry.expiresAt) return null
return entry.data
}Ten minutes is ten minutes. No mental arithmetic, no off-by-one when someone accidentally writes 60 * 60 instead of 60 * 1000.