0

Assuming I have:

t := 10 * time.Second // 10s, 

what's going on behind the scene when time.Second is applied again?

tt := t * time.Second // -2346317h47m53.709551616s

https://play.golang.org/p/upyjGgsuVQm

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Bryan
  • 105
  • 1
  • 8
  • `time.Second` is `1000000000`, what did you expect to happen? (or are you just asking about rollover to a negative value?) – JimB Jul 13 '20 at 20:39
  • 1
    the rollover to the negative value; initializing 10 * time.Second * time.Second throws an error, but I'm curious why it doesn't in the original post – Bryan Jul 13 '20 at 20:42
  • Don't multiply something that's already a `time.Duration` by one of the `Duration` constants; doing so doesn't make any sense. It's not clear what the intent of doing that would even be. – Adrian Jul 13 '20 at 20:45
  • 3
    `10 * time.Second * time.Second` is a constant expression. See the [specification for how constant expressions are evaluated](https://golang.org/ref/spec#Constant_expressions). – Charlie Tumahai Jul 13 '20 at 20:48

1 Answers1

2

A time.Duration value is a numeric value that represents number of nanoseconds.

A Duration represents the elapsed time between two instants as an int64 nanosecond count. The representation limits the largest representable duration to approximately 290 years.

type Duration int64

Whatever arithmetic you perform on time.Duration values, they are performed numerically just as on int64 values.

time.Second is a (typed) constant holding the number of nanoseconds in one second, so multiplying it by 10 will give you the number of nanoseconds in 10 seconds. This fits "perfectly" into an int64 number. As the documentation states, int64 may store number of nanoseconds up to about 290 years.

Now if t holds number of nanonseconds in 10 seconds, and you multiply that by the number of nanoseconds in 1 second, using 64-bit integers, that will overflow:

fmt.Println(math.MaxInt64)
fmt.Print(int64(10*time.Second), "*", int64(time.Second))

Outputs:

9223372036854775807
10000000000*1000000000

Note that t is a variable, and so overflow is OK. Constants in Go are exact values and do not overflow. So 10 * time.Second * time.Second would be a constant value that does not fit into int64 and hence it gives an error when you try to assign the result to a variable that's backed by an int64. For details see Does Go compiler's evaluation differ for constant expression and other expression

icza
  • 389,944
  • 63
  • 907
  • 827