A Go library that provides wall-clock aware alarms that fire at specific wall times, handling system clock adjustments gracefully.
Use it instead of time.NewTimer if you need to schedule an event at a specific time rather
than after some duration.
go get github.com/cardinalby/wallclockimport "github.com/cardinalby/wallclock"
fireAt, _ := time.Parse(time.RFC3339, "2026-01-01T09:00:00Z")
alarm := wallclock.NewAlarm(fireAt)
firedAt := <-alarm.C() // fires at 2026-01-01 09:00:00 (can be max 1 sec late) Timers are set to fire after a duration, but they don't account for changes in the system clock.
- If the clock jumps forward, timer fires too early
- If the clock jumps backward, timer fires too late
The lib use a timer internally, but is designed to fire at specific wall clock times:
- If the system clock jumps backward, we see it when a timer fires and reset it according to the new wall clock time.
- There is a background monitor that detects forward clock jumps and adjusts the timers accordingly.
- Thread-safe and efficient, uses internal event loop to manage alarms.
- Configurable delay tolerance to balance precision and CPU usage.
Optional params can be passed to NewAlarm() to control how sensitive the alarm is to clock jumps to the future
Sets the maximum allowed delay for the alarm. This controls how often the system checks for clock changes and how precise the firing time is. Default is 1 second.
alarm := wallclock.NewAlarm(
fireAt,
wallclock.WithAllowedDelay(time.Minute),
)Disables background clock jump-forward monitor for the alarm.
Jumps to the past will still be handled.
alarm := wallclock.NewAlarm(
fireAt,
wallclock.WithAnyAllowedDelay(),
)// Alarm is an interface that represents a timer that will fire at a specific wall time.
// It is designed to handle wall clock adjustments, ensuring that the alarm fires at the correct wall time
type Alarm interface {
// C returns a channel that will receive the time when the alarm fires.
// Channel is buffered and will receive a value only once
C() <-chan time.Time
// Stop stops the alarm, returning false if the alarm has already expired or been stopped
Stop() bool
}