AddDate()
引例
AddDate()
20221201
Go Time 包中是这么处理的
AddDate()Format()
只要是涉及到大小月的最后一天都会出现这个问题。
源码分析
10-31 + 1 monthAddDate()month+1Date()
Date()
- year 2020
- month 11
- day 31
- hour、min、sec、nsec 为运行时的时分秒纳秒
d 计算的是绝对纪元到今天之前的天数:
**d = 今年之前的天数 + 年初到当月之前的天数 + 月初到当天之前的天数;**
最终,将 d 转换成纳秒 + 当天经过的纳秒存储在 Time 对象中。
2022-11-312022-12-012022-11-312022-12-01
2022-11-352022-12-05
预期偏差
我们弄清楚了原理,但仍然不能接受这个结果。这样的结果是 Go 的 bug 吗?还是 Go Time 包偷懒了?
然而并不是,恰恰是我们的“预期”出现了问题。
10-301 month11-3010-311 month11-3010-31+1 month
+1 month
AddDate()
怎么解决
道理我都懂,但我就是想获取上/下一个月的最后一天怎么办?
利用前面源码分析阶段,提到的“天平原理”,就能拿到我们想要的结果。
结语
最初,发现这个问题是看鸟哥文章,当时认为那是 PHP 的“坑”,并没有深入思考过。如今,在 Go 语言再次遇到这个问题,重新思考,发现日期函数本应该就那么设计,是我们对日期函数理解不够,产生了错误的“预期”。
原文链接:https://segmentfault.com/a/1190000042502580