Skip to content

Support for custom time source (e.g. NTP) in cron scheduler #549

@aohanhongzhi

Description

@aohanhongzhi

Summary

Currently, cron/v3 relies solely on the system clock (time.Now()) for its scheduling logic. I'd like to request a feature that allows users to configure a custom time source, such as one provided by github.com/beevik/ntp, for cases where accurate timekeeping is critical and the system clock may not be reliable or synced in time.

On some embedded boards, the system time is initially incorrect because the application starts running before the NTP service has completed time synchronization. As a result, any time-based logic (e.g., scheduling with cron/v3) that relies on time.Now() may execute at unexpected times.

To address this, we often fetch the current time from an external NTP source (e.g., using github.com/beevik/ntp) and apply a delta to correct for the offset. However, since cron/v3 does not support injecting a custom time provider, we cannot align its scheduling with the corrected time reference.

Supporting a pluggable time source would greatly improve reliability in these environments.

Motivation

In some environments (e.g., embedded devices, VMs without NTP sync, or network-isolated systems), the system clock might drift or be incorrect. For these cases, relying on an external time source like NTP can ensure that scheduled tasks run at the expected wall-clock time.

For example, instead of using time.Now(), developers might want to plug in a function that returns a time from a trusted source like:

ntp.Time("pool.ntp.org")

Proposed Solution

Expose a functional option like:

cron.New(cron.WithTimeFunc(func() time.Time {
    return ntpTimeCache.Load().(time.Time)
}))

This would allow users to override the default time.Now() behavior used internally by the scheduler, similar to how logrus or other libraries allow customizable time providers.

Benefits

Supports more accurate scheduling when system time is unreliable

Useful in distributed systems or offline environments

Offers flexibility for advanced use cases without affecting default behavior

Compatibility

This would be an opt-in feature and fully backward compatible. If no custom time function is set, cron continues using time.Now() as usual.

Thanks

Thanks for the great work on cron — it's been very helpful! Let me know if you're open to a PR or if you'd prefer to discuss design first.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions