You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中正确获取上月日期的方法(解决AddDate异常)

Go语言中正确获取上月日期的方法

当使用time.AddDate()处理月末日期时,会因为日期规范化逻辑导致结果不符合预期。比如你提到的例子:

mayEndDate := time.Date(2021, 5, 31, 12, 00, 00, 00, time.UTC)
finalDate := mayEndDate.AddDate(0, -1, 0) // 修正原代码变量名笔误

运行后finalDate得到2021-05-01 12:00:00 +0000 UTC,而非预期的4月日期。原因是AddDate会自动规范化不存在的日期:5月31日减1个月会试图构造4月31日,但4月只有30天,因此被调整为5月1日。

以下是两种可靠的解决方案:

方法一:通过当月第一天倒推上月最后一天

先获取当前日期所在月份的第一天,再减去1天,就能得到上月的最后一天,同时可以保留原日期的时分秒信息:

mayEndDate := time.Date(2021, 5, 31, 12, 0, 0, 0, time.UTC)
// 获取当月第一天(时分秒设为0)
firstDayOfCurrMonth := time.Date(mayEndDate.Year(), mayEndDate.Month(), 1, 0, 0, 0, 0, mayEndDate.Location())
// 减1天得到上月最后一天,并保留原日期的时分秒
lastDayOfPrevMonth := time.Date(
    firstDayOfCurrMonth.AddDate(0, 0, -1).Year(),
    firstDayOfCurrMonth.AddDate(0, 0, -1).Month(),
    firstDayOfCurrMonth.AddDate(0, 0, -1).Day(),
    mayEndDate.Hour(), mayEndDate.Minute(), mayEndDate.Second(), mayEndDate.Nanosecond(),
    mayEndDate.Location(),
)
// 输出:2021-04-30 12:00:00 +0000 UTC

方法二:构造上月日期后校验修正

先尝试构造上月的相同日期,如果构造后的月份不是预期的上月,则说明上月没有该日期,此时取上月的最后一天:

func getPrevMonthDate(t time.Time) time.Time {
    year, month, day := t.Date()
    loc := t.Location()
    // 尝试构造上月的相同日期
    prevDate := time.Date(year, month-1, day, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), loc)
    // 校验是否为上月,若不是则取上月最后一天
    if prevDate.Month() != month-1 {
        prevDate = time.Date(year, month, 1, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), loc).AddDate(0, 0, -1)
    }
    return prevDate
}

// 使用示例
mayEndDate := time.Date(2021, 5, 31, 12, 0, 0, 0, time.UTC)
finalDate := getPrevMonthDate(mayEndDate)
// 输出:2021-04-30 12:00:00 +0000 UTC

这两种方法都能避免AddDate的规范化问题,准确得到上月的对应日期(月末日期会自动适配上月最后一天)。

内容的提问来源于stack exchange,提问作者Ayush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 14:05:22