mirror of
https://github.com/golang/go
synced 2024-11-18 11:55:01 -07:00
time: strip monotonic time in t.Round, t.Truncate
The original analysis of the Go corpus assumed that these stripped monotonic time. During the design discussion we decided to try not stripping monotonic time here, but existing code works better if we do. See the discussion on golang.org/issue/18991 for more details. For #18991. Change-Id: I04d355ffe56ca0317acdd2ca76cb3033c277f6d1 Reviewed-on: https://go-review.googlesource.com/37542 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
f072283bce
commit
6c85fb08c2
@ -54,8 +54,8 @@ func TestHasMonotonicClock(t *testing.T) {
|
|||||||
yes("tm.In(UTC)", tm.In(UTC))
|
yes("tm.In(UTC)", tm.In(UTC))
|
||||||
yes("tm.Local()", tm.Local())
|
yes("tm.Local()", tm.Local())
|
||||||
yes("tm.UTC()", tm.UTC())
|
yes("tm.UTC()", tm.UTC())
|
||||||
yes("tm.Round(2)", tm.Round(2))
|
no("tm.Round(2)", tm.Round(2))
|
||||||
yes("tm.Truncate(2)", tm.Truncate(2))
|
no("tm.Truncate(2)", tm.Truncate(2))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMonotonicAdd(t *testing.T) {
|
func TestMonotonicAdd(t *testing.T) {
|
||||||
|
@ -37,13 +37,12 @@
|
|||||||
// to use this package.
|
// to use this package.
|
||||||
//
|
//
|
||||||
// The Time returned by time.Now contains a monotonic clock reading.
|
// The Time returned by time.Now contains a monotonic clock reading.
|
||||||
// If Time t has a monotonic clock reading, t.Add, t.Round, and
|
// If Time t has a monotonic clock reading, t.Add adds the same duration to
|
||||||
// t.Truncate add the same duration to both the wall clock and
|
// both the wall clock and monotonic clock readings to compute the result.
|
||||||
// monotonic clock readings to compute the result. Similarly, t.In,
|
// Similarly, t.In, t.Local, and t.UTC, which are defined to change only the Time's
|
||||||
// t.Local, and t.UTC, which are defined to change only the Time's
|
|
||||||
// Location, pass any monotonic clock reading through unmodified.
|
// Location, pass any monotonic clock reading through unmodified.
|
||||||
// Because t.AddDate(y, m, d) is a wall time computation, it always
|
// Because t.AddDate(y, m, d), t.Round(d), and t.Truncate(d) are wall time
|
||||||
// strips any monotonic clock reading from its result.
|
// computations, they always strip any monotonic clock reading from their results.
|
||||||
//
|
//
|
||||||
// If Times t and u both contain monotonic clock readings, the operations
|
// If Times t and u both contain monotonic clock readings, the operations
|
||||||
// t.After(u), t.Before(u), t.Equal(u), and t.Sub(u) are carried out
|
// t.After(u), t.Before(u), t.Equal(u), and t.Sub(u) are carried out
|
||||||
@ -172,8 +171,7 @@ func (t *Time) addSec(d int64) {
|
|||||||
}
|
}
|
||||||
// Wall second now out of range for packed field.
|
// Wall second now out of range for packed field.
|
||||||
// Move to ext.
|
// Move to ext.
|
||||||
t.ext = t.sec()
|
t.stripMono()
|
||||||
t.wall &= nsecMask
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Check for overflow.
|
// TODO: Check for overflow.
|
||||||
@ -188,6 +186,14 @@ func (t *Time) setLoc(loc *Location) {
|
|||||||
t.loc = loc
|
t.loc = loc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stripMono strips the monotonic clock reading in t.
|
||||||
|
func (t *Time) stripMono() {
|
||||||
|
if t.wall&hasMonotonic != 0 {
|
||||||
|
t.ext = t.sec()
|
||||||
|
t.wall &= nsecMask
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// setMono sets the monotonic clock reading in t.
|
// setMono sets the monotonic clock reading in t.
|
||||||
// If t cannot hold a monotonic clock reading,
|
// If t cannot hold a monotonic clock reading,
|
||||||
// because its wall time is too large,
|
// because its wall time is too large,
|
||||||
@ -839,8 +845,7 @@ func (t Time) Add(d Duration) Time {
|
|||||||
te := t.ext + int64(d)
|
te := t.ext + int64(d)
|
||||||
if d < 0 && te > int64(t.ext) || d > 0 && te < int64(t.ext) {
|
if d < 0 && te > int64(t.ext) || d > 0 && te < int64(t.ext) {
|
||||||
// Monotonic clock reading now out of range; degrade to wall-only.
|
// Monotonic clock reading now out of range; degrade to wall-only.
|
||||||
t.ext = t.sec()
|
t.stripMono()
|
||||||
t.wall &= nsecMask
|
|
||||||
} else {
|
} else {
|
||||||
t.ext = te
|
t.ext = te
|
||||||
}
|
}
|
||||||
@ -1373,6 +1378,7 @@ func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) T
|
|||||||
// time. Thus, Truncate(Hour) may return a time with a non-zero
|
// time. Thus, Truncate(Hour) may return a time with a non-zero
|
||||||
// minute, depending on the time's Location.
|
// minute, depending on the time's Location.
|
||||||
func (t Time) Truncate(d Duration) Time {
|
func (t Time) Truncate(d Duration) Time {
|
||||||
|
t.stripMono()
|
||||||
if d <= 0 {
|
if d <= 0 {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
@ -1389,6 +1395,7 @@ func (t Time) Truncate(d Duration) Time {
|
|||||||
// time. Thus, Round(Hour) may return a time with a non-zero
|
// time. Thus, Round(Hour) may return a time with a non-zero
|
||||||
// minute, depending on the time's Location.
|
// minute, depending on the time's Location.
|
||||||
func (t Time) Round(d Duration) Time {
|
func (t Time) Round(d Duration) Time {
|
||||||
|
t.stripMono()
|
||||||
if d <= 0 {
|
if d <= 0 {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user