Files
quic-go/internal/monotime/time.go
Marten Seemann adc13be540 implement a memory-optimized time.Time replacement (#5334)
* implement a memory-optimized time.Time replacement

* monotime: properly handle systems with bad timer resolution (Windows)

* monotime: simplify Since
2025-09-14 08:12:10 +02:00

91 lines
2.6 KiB
Go

// Package monotime provides a monotonic time representation that is useful for
// measuring elapsed time.
// It is designed as a memory optimized drop-in replacement for time.Time, with
// a monotime.Time consuming just 8 bytes instead of 24 bytes.
package monotime
import (
"time"
)
// The absolute value doesn't matter, but it should be in the past,
// so that every timestamp obtained with Now() is non-zero,
// even on systems with low timer resolutions (e.g. Windows).
var start = time.Now().Add(-time.Hour)
// A Time represents an instant in monotonic time.
// Times can be compared using the comparison operators, but the specific
// value is implementation-dependent and should not be relied upon.
// The zero value of Time doesn't have any specific meaning.
type Time int64
// Now returns the current monotonic time.
func Now() Time {
return Time(time.Since(start).Nanoseconds())
}
// Sub returns the duration t-t2. If the result exceeds the maximum (or minimum)
// value that can be stored in a Duration, the maximum (or minimum) duration
// will be returned.
// To compute t-d for a duration d, use t.Add(-d).
func (t Time) Sub(t2 Time) time.Duration {
return time.Duration(t - t2)
}
// Add returns the time t+d.
func (t Time) Add(d time.Duration) Time {
return Time(int64(t) + d.Nanoseconds())
}
// After reports whether the time instant t is after t2.
func (t Time) After(t2 Time) bool {
return t > t2
}
// Before reports whether the time instant t is before t2.
func (t Time) Before(t2 Time) bool {
return t < t2
}
// IsZero reports whether t represents the zero time instant.
func (t Time) IsZero() bool {
return t == 0
}
// Equal reports whether t and t2 represent the same time instant.
func (t Time) Equal(t2 Time) bool {
return t == t2
}
// ToTime converts the monotonic time to a time.Time value.
// The returned time.Time will have the same instant as the monotonic time,
// but may be subject to clock adjustments.
func (t Time) ToTime() time.Time {
if t.IsZero() {
return time.Time{}
}
return start.Add(time.Duration(t))
}
// Since returns the time elapsed since t. It is shorthand for Now().Sub(t).
func Since(t Time) time.Duration {
return Now().Sub(t)
}
// Until returns the duration until t.
// It is shorthand for t.Sub(Now()).
// If t is in the past, the returned duration will be negative.
func Until(t Time) time.Duration {
return time.Duration(t - Now())
}
// FromTime converts a time.Time to a monotonic Time.
// The conversion is relative to the package's start time and may lose
// precision if the time.Time is far from the start time.
func FromTime(t time.Time) Time {
if t.IsZero() {
return 0
}
return Time(t.Sub(start).Nanoseconds())
}