/* Copyright (c) 2015-2016 Christopher Young Distributable under the terms of The "BSD New"" License that can be found in the LICENSE file, herein included as part of this header. Modifications (c) 2016 AvSquirrel (https://github.com/AvSquirrel) monotonic.go: Create monotonic clock using time.Timer - necessary because of real time clock changes on RPi. */ package main import ( humanize "github.com/dustin/go-humanize" "time" ) // Timer (since start). type monotonic struct { Milliseconds uint64 Time time.Time ticker *time.Ticker realTimeSet bool RealTime time.Time } func (m *monotonic) Watcher() { for { <-m.ticker.C m.Milliseconds += 10 m.Time = m.Time.Add(10 * time.Millisecond) if m.realTimeSet { m.RealTime = m.RealTime.Add(10 * time.Millisecond) } } } func (m *monotonic) Since(t time.Time) time.Duration { return m.Time.Sub(t) } func (m *monotonic) HumanizeTime(t time.Time) string { return humanize.RelTime(t, m.Time, "ago", "from now") } func (m *monotonic) Unix() int64 { return int64(m.Since(time.Time{}).Seconds()) } func (m *monotonic) HasRealTimeReference() bool { return m.realTimeSet } func (m *monotonic) SetRealTimeReference(t time.Time) { if !m.realTimeSet { // Only allow the real clock to be set once. m.RealTime = t m.realTimeSet = true } } func NewMonotonic() *monotonic { t := &monotonic{Milliseconds: 0, Time: time.Time{}, ticker: time.NewTicker(10 * time.Millisecond)} go t.Watcher() return t }