go 时间戳转换需注意的坑,int64 -> float64

项目中遇到的一个小问题,做个记录:go 标准库 json.Unmarshal 当使用 interface{} 接收 int 类型的值时,会将其转换为 float64,这样也合理,本篇不深究 json 库的实现。

当直接使用 interface{} 来接收参数时,是不会转换其类型的,如下:

func tInterfaceTimestamp() {
    
    
	nowTimestamp := time.Now().Unix()
	fmt.Println("当前时间戳秒:", nowTimestamp)

	var i interface{
    
    } = nowTimestamp
	fmt.Println(reflect.TypeOf(i))
}

输出如下:

当前时间戳秒: 1636619064
int64

但是当我们使用 json 来做一次转换时,就发现了 int64 转变成了 float64,如下:

func tJsonTimestamp() {
    
    
	type test struct {
    
    
		Timestamp int64
	}
	var data = test{
    
    time.Now().Unix()}
	buf, _ := json.Marshal(data)

	var data2 = struct{
    
     Timestamp interface{
    
    } }{
    
    }
	json.Unmarshal(buf, &data2)
	fmt.Println(reflect.TypeOf(data2.Timestamp))

	var resMap = make(map[string]interface{
    
    })
	if er := json.Unmarshal(buf, &resMap); er != nil {
    
    
		fmt.Println(er)
		return
	}

	t, ok := resMap["Timestamp"]
	if !ok {
    
    
		return
	}

	fmt.Println(reflect.TypeOf(t))
}

输出:

float64
float64

顺带附上一个转换时间戳为 string 字符串的小方法,精确到秒

func GetTimestampStr(ts int64) string {
    
    
	sLength := 10 // 以秒来做精度
	str := strconv.FormatInt(ts, 10)
	tsLength := len(str)
	if tsLength < sLength {
    
    
		fmt.Println("====== 时间戳小于10啦:", ts)
		return ""
	}

	multiple := tsLength - sLength
	if multiple > 0 {
    
    
		ts = ts / (int64(math.Pow10(multiple)))
	}
	// 这里不用考虑时区,时间戳会根据当前操作系统的时区进行转换
	return time.Unix(ts, 0).Format("2006-01-02 15:04:05")
}

上述所有代码都在我的 Gitee仓库/timeTest包里,该仓库还包含了日常的一些测试代码等,感兴趣的可以看下。

猜你喜欢

转载自blog.csdn.net/DisMisPres/article/details/121270333
今日推荐