Go's zero time is year 1, not 1970 or something Unix-y like that. That's fine.
Except:
func main() {
origin := time.Time{}
t := time.Date(2025, 1, 16, 4, 0, 0, 0, time.UTC)
d := t.Sub(origin)
t2 := origin.Add(d)
fmt.Println(t2)
}
results in 0293-04-11 23:47:16.854775807 +0000 UTC
https://go.dev/play/p/turgQXfyJG-
There's obviously an integer overflow happening here and it's too late in the day for me to figure out how to work around it.
What I need to do is truncate times to a 64-hour or 256-hour boundary. Our existing Go code truncates relative to Go's zero time. TimescaleDB truncates relative to 2001-01-01, or 2001-01-03 in some cases when calculating buckets. It seems challenging to write code that handles both, if the invariant t.Sub(origin).Add(origin) == t does not hold.
https://pkg.go.dev/time#Duration :
> 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.
and so .Sub caps the return value:
https://pkg.go.dev/time#Time.Sub :
> If the result exceeds the maximum (or minimum) value that can be stored in a Duration, the maximum (or minimum) duration will be returned.
@lukeshu Thanks.
I guess what I need to do is figure out some time in the last couple hundred years that has the same alignment as the actual zero time (using Truncate on the largest interval I care about.)
@markgritter @lukeshu depends on what your usecase is, but you could use t.Unix (or the Milli, Micro and Nano variants).