Help!time package bug?

package main

import (
	"fmt"
	"time"
)

func main() {
	FORMAT := "2006-01-02 15:04:05"
	a := time.Now()
	fmt.Println("Now:", time.Now().Format(FORMAT))
	fmt.Println("A:", a.Format(FORMAT), a.Unix(), a.UnixNano())

	fmt.Println("\nSleep...\n")
	time.Sleep(time.Second * 10)
	fmt.Println("Now:", time.Now().Format(FORMAT))

	b := a.Add(5 * time.Hour)
	c := time.Now()

	fmt.Println("B:", b.Format(FORMAT), b.Unix(), b.UnixNano())
	fmt.Println("C:", c.Format(FORMAT), c.Unix(), c.UnixNano())

	if b.After(c) {
		fmt.Println("After,B after C")
	} else {
		fmt.Println("After,B is not after C")
	}

	if b.Unix() >= c.Unix() {
		fmt.Println("Unix,B after C")
	} else {
		fmt.Println("Unix,B is not after C")
	}

	if b.UnixNano() >= c.UnixNano() {
		fmt.Println("UnixNano,B after C")
	} else {
		fmt.Println("UnixNano,B is not after C")
	}
}

Go version:
go version go1.14.1 windows/amd64
go version go1.15.6 windows/amd64

When sleeping,modify system time(add one day),‘After’ function return true?

Why?

1 Like

Looks like a bug. Can you contact the developers by emailing to https://groups.google.com/g/golang-nuts

I can’t reproduce your issue on Debian amd64.

u0:test$ go run main.go 
Now: 2020-12-10 18:12:28
A: 2020-12-10 18:12:28 1607595148 1607595148476836765

Sleep...

Now: 2020-12-10 18:12:38
B: 2020-12-10 23:12:28 1607613148 1607613148476836765
C: 2020-12-10 18:12:38 1607595158 1607595158477300968
After,B after C
Unix,B after C
UnixNano,B after C
u0:test$ go run main.go 
Now: 2020-12-10 18:12:40
A: 2020-12-10 18:12:40 1607595160 1607595160732716728

Sleep...

Now: 2020-12-10 18:12:50
B: 2020-12-10 23:12:40 1607613160 1607613160732716728
C: 2020-12-10 18:12:50 1607595170 1607595170733191244
After,B after C
Unix,B after C
UnixNano,B after C

On go version go1.15.2 linux/amd64.

Apparently, on your 2nd execution, unknown reason causes C’s Unix format to misbehave. The value should be closer to A, not B.

When code run at time.Sleep(time.Second * 10),modify you operating system time(add one day).

Monotonic clock versus wall clock. Read Package time: Monotonic Clocks.

Run your test using this version of your code and post your output as text, not as an image.

package main

import (
	"fmt"
	"time"
)

func main() {
	FORMAT := "2006-01-02 15:04:05"
	a := time.Now()
	fmt.Println("Now:", time.Now().Format(FORMAT))
	fmt.Println("A:", a.Format(FORMAT), a.Unix(), a.UnixNano())

	fmt.Println("\nSleep...\n")
	time.Sleep(time.Second * 10)
	fmt.Println("Now:", time.Now().Format(FORMAT))

	b := a.Add(5 * time.Hour)
	c := time.Now()

	fmt.Println("B:", b.Format(FORMAT), b.Unix(), b.UnixNano())
	fmt.Println("C:", c.Format(FORMAT), c.Unix(), c.UnixNano())

	fmt.Println()
	fmt.Println("Monotonic Clock (m):")
	fmt.Println("A:", a)
	fmt.Println("B:", b)
	fmt.Println("C:", c)
	fmt.Println("B after C:", b.After(c))
	fmt.Println("Wall Clock:")
	fmt.Println("A:", a.Round(0))
	fmt.Println("B:", b.Round(0))
	fmt.Println("C:", c.Round(0))
	fmt.Println("B after C:", b.Round(0).After(c.Round(0)))
	fmt.Println()

    fmt.Println("Monotonic Clock")
	if b.After(c) {
		fmt.Println("After,B after C")
	} else {
		fmt.Println("After,B is not after C")
	}

    fmt.Println("Wall Clock")
	if b.Unix() >= c.Unix() {
		fmt.Println("Unix,B after C")
	} else {
		fmt.Println("Unix,B is not after C")
	}

    fmt.Println("Wall Clock")
	if b.UnixNano() >= c.UnixNano() {
		fmt.Println("UnixNano,B after C")
	} else {
		fmt.Println("UnixNano,B is not after C")
	}
}

.

Monotonic Clock (m):
A: 2020-12-10 06:53:48.766741505 -0500 EST m=+0.000081695
B: 2020-12-10 11:53:48.766741505 -0500 EST m=+18000.000081695
C: 2020-12-10 06:53:58.776090071 -0500 EST m=+10.009429982
B after C: true
Wall Clock:
A: 2020-12-10 06:53:48.766741505 -0500 EST
B: 2020-12-10 11:53:48.766741505 -0500 EST
C: 2020-12-10 06:53:58.776090071 -0500 EST
B after C: true

Monotonic Clock
After,B after C
Wall Clock
Unix,B after C
Wall Clock
UnixNano,B after C

Known reason: Package time: Monotonic Clocks.

Please don’t. Read Package time: Monotonic Clocks.

1 Like

ok,so i need use ‘Round’ function,time comparison will be right?

The canonical way to strip a monotonic clock reading is to use t = t.Round(0).

That will ensure that the time is a wall clock (system) time.

1 Like

ok,i got it.

Thanks

I was not aware of the hour addition to the wall clock. In that case, @petrus is right. There is a difference between wall clock and monotonic clock.

I was too focused on the OS differences and didn’t notice there is a tweak.

EDIT: sorry, was out to dinner.