kaspad/util/mstime/mstime.go
Ori Newman 749775c7ea
[NOD-1098] Change timestamp precision to one millisecond (#778)
* [NOD-1098] Change timestamps to be millisecond precision

* [NOD-1098] Change lock times to use milliseconds

* [NOD-1098] Use milliseconds precision everywhere

* [NOD-1098] Implement type mstime.Time

* [NOD-1098] Fix block 100000 timestamp

* [NOD-1098] Change orphan child to be one millisecond delay after its parent

* [NOD-1098] Remove test that checks if header timestamps have the right precision, and instead add tests for mstime, and fix genesis for testnet and devnet

* [NOD-1098] Fix comment

* [NOD-1098] Fix comment

* [NOD-1098] Fix testnet genesis

* [NOD-1098] Rename UnixMilli->UnixMilliseconds
2020-07-01 16:09:04 +03:00

122 lines
3.4 KiB
Go

package mstime
import (
"github.com/pkg/errors"
"time"
)
const (
nanosecondsInMillisecond = int64(time.Millisecond / time.Nanosecond)
millisecondsInSecond = int64(time.Second / time.Millisecond)
)
// Time is a wrapper for time.Time that guarantees all of its methods will return a millisecond precisioned times.
type Time struct {
time time.Time
}
// UnixMilliseconds returns t as a Unix time, the number of milliseconds elapsed
// since January 1, 1970 UTC.
func (t Time) UnixMilliseconds() int64 {
return t.time.UnixNano() / nanosecondsInMillisecond
}
// UnixSeconds returns t as a Unix time, the number of seconds elapsed
// since January 1, 1970 UTC.
func (t Time) UnixSeconds() int64 {
return t.time.Unix()
}
// String returns the time formatted using the format string
// "2006-01-02 15:04:05.999999999 -0700 MST"
func (t Time) String() string {
return t.time.String()
}
// Clock returns the hour, minute, and second within the day specified by t.
func (t Time) Clock() (hour, min, sec int) {
return t.time.Clock()
}
// Millisecond returns the millisecond offset within the second specified by t,
// in the range [0, 999].
func (t Time) Millisecond() int {
return t.time.Nanosecond() / int(nanosecondsInMillisecond)
}
// Date returns the year, month, and day in which t occurs.
func (t Time) Date() (year int, month time.Month, day int) {
return t.time.Date()
}
// After reports whether the time instant t is after u.
func (t Time) After(u Time) bool {
return t.time.After(u.time)
}
// Before reports whether the time instant t is before u.
func (t Time) Before(u Time) bool {
return t.time.Before(u.time)
}
// Add returns the time t+d.
// It panics if d has a precision greater than one millisecond (the duration has a non zero microseconds part).
func (t Time) Add(d time.Duration) Time {
validateDurationPrecision(d)
return newMSTime(t.time.Add(d))
}
// Sub returns the duration t-u. 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(u Time) time.Duration {
return t.time.Sub(u.time)
}
// IsZero reports whether t represents the zero time instant,
// January 1, year 1, 00:00:00 UTC.
func (t Time) IsZero() bool {
return t.time.IsZero()
}
// ToNativeTime converts t to time.Time
func (t Time) ToNativeTime() time.Time {
return t.time
}
// Now returns the current local time, with precision of one millisecond.
func Now() Time {
return ToMSTime(time.Now())
}
// UnixMilliseconds returns the local Time corresponding to the given Unix time,
// ms milliseconds since January 1, 1970 UTC.
func UnixMilliseconds(ms int64) Time {
seconds := ms / millisecondsInSecond
nanoseconds := (ms - seconds*millisecondsInSecond) * nanosecondsInMillisecond
return newMSTime(time.Unix(ms/millisecondsInSecond, nanoseconds))
}
// Since returns the time elapsed since t.
// It is shorthand for Now().Sub(t).
func Since(t Time) time.Duration {
return Now().Sub(t)
}
// ToMSTime converts t to Time.
// See Time for details.
func ToMSTime(t time.Time) Time {
return newMSTime(t.Round(time.Millisecond))
}
func newMSTime(t time.Time) Time {
return Time{time: t}
}
func validateDurationPrecision(d time.Duration) {
if d.Nanoseconds()%nanosecondsInMillisecond != 0 {
panic(errors.Errorf("duration %s has lower precision than millisecond", d))
}
}