为何time.AddDate()无法为仅解析时间的对象添加当日日期?
问题分析与解决
这是Go语言里一个很常见的坑——time.Time是不可变的值类型!你调用AddDate()的时候,它并不会修改原来的t1对象,而是返回一个全新的时间实例,你没把这个返回值赋值回t1,所以原变量自然没变化。
修正方案一:正确接收AddDate()的返回值
注意这里要调整月份和日期的增量,因为t1初始的日期是0000-01-01,所以要计算从1月1日到当前月日的增量:
func main() { t1, _ := time.Parse("03:04:05", "12:03:30") fmt.Printf("current date time %v\n", t1) now := time.Now().UTC() // 关键:将AddDate的返回值重新赋值给t1 t1 = t1.AddDate(now.Year(), int(now.Month())-1, now.Day()-1) fmt.Printf("current date time %v", t1) }
修正方案二:直接构造新时间(更直观推荐)
相比用AddDate计算增量,直接用当前日期和解析出的时间部分构造新时间会更清晰,不容易出错:
func main() { t1, _ := time.Parse("03:04:05", "12:03:30") fmt.Printf("current date time %v\n", t1) now := time.Now().UTC() // 用当前的年/月/日,加上t1的时/分/秒/纳秒和时区构造新时间 t1 = time.Date(now.Year(), now.Month(), now.Day(), t1.Hour(), t1.Minute(), t1.Second(), t1.Nanosecond(), now.Location()) fmt.Printf("current date time %v", t1) }
为什么原代码没效果?
Go设计time.Time为不可变类型是为了线程安全——因为值类型在传递时是拷贝,不可变的特性避免了并发场景下的竞态问题。所有修改时间的方法(比如Add、AddDate、Local等)都会返回新实例,原实例保持不变,所以一定要记得接收返回值!
内容的提问来源于stack exchange,提问作者Katherine Dudo
相关产品推荐
相关产品推荐

