first version
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
package timeutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Clock interface {
|
||||
Now() time.Time
|
||||
Sleep(ctxDone <-chan struct{}, d time.Duration) bool
|
||||
}
|
||||
|
||||
type RealClock struct {
|
||||
Loc *time.Location
|
||||
}
|
||||
|
||||
func (c RealClock) Now() time.Time {
|
||||
now := time.Now()
|
||||
if c.Loc != nil {
|
||||
return now.In(c.Loc)
|
||||
}
|
||||
return now
|
||||
}
|
||||
|
||||
func (c RealClock) Sleep(ctxDone <-chan struct{}, d time.Duration) bool {
|
||||
timer := time.NewTimer(d)
|
||||
defer timer.Stop()
|
||||
select {
|
||||
case <-timer.C:
|
||||
return true
|
||||
case <-ctxDone:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
type TimeOfDay struct {
|
||||
Duration time.Duration
|
||||
}
|
||||
|
||||
func ParseTimeOfDay(raw string) (TimeOfDay, error) {
|
||||
parsed, err := time.Parse("15:04:05", raw)
|
||||
if err != nil {
|
||||
return TimeOfDay{}, fmt.Errorf("parse time of day %q: %w", raw, err)
|
||||
}
|
||||
return TimeOfDay{
|
||||
Duration: time.Duration(parsed.Hour())*time.Hour +
|
||||
time.Duration(parsed.Minute())*time.Minute +
|
||||
time.Duration(parsed.Second())*time.Second,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (t *TimeOfDay) UnmarshalText(text []byte) error {
|
||||
parsed, err := ParseTimeOfDay(string(text))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*t = parsed
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t TimeOfDay) String() string {
|
||||
total := int64(t.Duration.Seconds())
|
||||
h := total / 3600
|
||||
m := (total % 3600) / 60
|
||||
s := total % 60
|
||||
return fmt.Sprintf("%02d:%02d:%02d", h, m, s)
|
||||
}
|
||||
|
||||
func (t TimeOfDay) On(date time.Time, loc *time.Location) time.Time {
|
||||
local := date.In(loc)
|
||||
y, m, d := local.Date()
|
||||
midnight := time.Date(y, m, d, 0, 0, 0, 0, loc)
|
||||
return midnight.Add(t.Duration)
|
||||
}
|
||||
|
||||
type Window struct {
|
||||
Start TimeOfDay
|
||||
End TimeOfDay
|
||||
}
|
||||
|
||||
func (w Window) Contains(now time.Time, loc *time.Location) bool {
|
||||
start := w.Start.On(now, loc)
|
||||
end := w.End.On(now, loc)
|
||||
return !now.Before(start) && now.Before(end)
|
||||
}
|
||||
|
||||
func Drift(local, server time.Time) time.Duration {
|
||||
d := local.Sub(server)
|
||||
if d < 0 {
|
||||
return -d
|
||||
}
|
||||
return d
|
||||
}
|
||||
Reference in New Issue
Block a user