我有个习惯,就是把一些比较固定的东西会写在常量里,比如一些key的过期时间,就会定义constant keyExpireDuration = 10*time.Second, 有一天,需要将这个过期时间戳返回给前端,然后我就没脑的使用了time.now.unix() + int64(xxx),然后就爆了

Duration类型是time包里定义的一个类型,实际上的类型是int64。 我们从time包定义的常量来分析

1
2
3
4
5
6
7
8
const (
	Nanosecond  Duration = 1
	Microsecond          = 1000 * Nanosecond
	Millisecond          = 1000 * Microsecond
	Second               = 1000 * Millisecond
	Minute               = 60 * Second
	Hour                 = 60 * Minute
)

可以发现duration最小的单位是ns, 我们代码里如果使用的是time.Second,实际上对应的duration的值是纳秒为单位的。 当我们如果进行运算的时候,就得注意了。比如简单的time.now.unix() + int64(xxx)相加,最后导致的前面一个是秒级的时间戳, 而后面一个是纳秒级的数字,这相加导致最终的结果爆掉了。

正确的做法就是需要相加的比如是10 * time.Second,我们需要先除以time.Second来保证这是秒数,而不是纳秒数

这就是小小的时间相加可能导致的问题。

1
2
expireDuration := 10 * time.Second
expireTime := time.now.unix() + int64(expireTime/time.Second)