如何在Golang加上一个月的预期结果

svmlkihl  于 2023-04-27  发布在  Go
关注(0)|答案(3)|浏览(157)

这是我在Golang的代码

dateTime := "2023-01-31T15:51:00Z"
layout := "2006-01-02T15:04:00Z"

time, _ := time.Parse(layout, dateTime)

next1Month := time.AddDate(0, 1, 0) // result is 2023-03-03 15:51:00 +0000 UTC
next2Month := time.AddDate(0, 2, 0) // result is 2023-03-31 15:51:00 +0000 UTC
next3Month := time.AddDate(0, 3, 0) // result is 2023-05-01 15:51:00 +0000 UTC

我的期望

next1Month is  2023-02-28 15:51:00 +0000 UTC
next2Month is 2023-03-31 15:51:00 +0000 UTC
next3Month is 2023-04-31 15:51:00 +0000 UTC

请帮助我与任何关键字或解决方案来解决它。

svujldwt

svujldwt1#

十进制算术是连续的。DateTime算术不是连续的:日期时间算法没有固定的规则,它取决于上下文。没有上下文,就不可能确切地知道你想要什么。
下面是DateTime算法的一种形式,它可以产生预期的结果。

2023-01-31 15:51:00 +0000 UTC : months 0
2023-02-28 15:51:00 +0000 UTC : months 1
2023-03-31 15:51:00 +0000 UTC : months 2
2023-04-30 15:51:00 +0000 UTC : months 3
package main

import (
    "fmt"
    "time"
)

func addMonths(t time.Time, months int) time.Time {
    add := t.AddDate(0, months, 0)
    day := t.Day()
    lastAdd := t.AddDate(0, months+1, -day)
    if add.After(lastAdd) {
        return lastAdd
    }
    last := t.AddDate(0, 1, -day)
    if t.Equal(last) {
        return lastAdd
    }
    return add
}

func main() {
    dateTime := "2023-01-31T15:51:00Z"
    layout := "2006-01-02T15:04:00Z"
    date, err := time.Parse(layout, dateTime)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println()
    for days := 0; days >= -3; days-- {
        date := date
        date = date.AddDate(0, 0, days)
        fmt.Println(date, ": days", days)
        for months := -1; months <= 4; months++ {
            next := addMonths(date, months)
            fmt.Println(next, ": months", months)
        }
        fmt.Println()
    }
}

https://go.dev/play/p/NLqtlu2OmZ0

2023-01-31 15:51:00 +0000 UTC : days 0
2022-12-31 15:51:00 +0000 UTC : months -1
2023-01-31 15:51:00 +0000 UTC : months 0
2023-02-28 15:51:00 +0000 UTC : months 1
2023-03-31 15:51:00 +0000 UTC : months 2
2023-04-30 15:51:00 +0000 UTC : months 3
2023-05-31 15:51:00 +0000 UTC : months 4

2023-01-30 15:51:00 +0000 UTC : days -1
2022-12-30 15:51:00 +0000 UTC : months -1
2023-01-30 15:51:00 +0000 UTC : months 0
2023-02-28 15:51:00 +0000 UTC : months 1
2023-03-30 15:51:00 +0000 UTC : months 2
2023-04-30 15:51:00 +0000 UTC : months 3
2023-05-30 15:51:00 +0000 UTC : months 4

2023-01-29 15:51:00 +0000 UTC : days -2
2022-12-29 15:51:00 +0000 UTC : months -1
2023-01-29 15:51:00 +0000 UTC : months 0
2023-02-28 15:51:00 +0000 UTC : months 1
2023-03-29 15:51:00 +0000 UTC : months 2
2023-04-29 15:51:00 +0000 UTC : months 3
2023-05-29 15:51:00 +0000 UTC : months 4

2023-01-28 15:51:00 +0000 UTC : days -3
2022-12-28 15:51:00 +0000 UTC : months -1
2023-01-28 15:51:00 +0000 UTC : months 0
2023-02-28 15:51:00 +0000 UTC : months 1
2023-03-28 15:51:00 +0000 UTC : months 2
2023-04-28 15:51:00 +0000 UTC : months 3
2023-05-28 15:51:00 +0000 UTC : months 4
a14dhokn

a14dhokn2#

AddDate只是执行基本的数学运算,但你似乎在寻找“本月的最后一天”,这不是简单的数学运算,它需要逻辑。你必须实现这个逻辑。例如,你可以使用每月的1号减去1天:https://go.dev/play/p/Prc7_5rY3K9

dateTime := "2023-02-01T15:51:00Z"
layout := "2006-01-02T15:04:00Z"

time, _ := time.Parse(layout, dateTime)

next1Month := time.AddDate(0, 2, -1)
next2Month := time.AddDate(0, 3, -1)
next3Month := time.AddDate(0, 4, -1)

输出:

2023-03-31 15:51:00 +0000 UTC
2023-04-30 15:51:00 +0000 UTC
2023-05-31 15:51:00 +0000 UTC
gmol1639

gmol16393#

我修好了

func AddMonth(t time.Time, m int) time.Time {
    x := t.AddDate(0, m, 0)

    if d := x.Day(); d != t.Day() {
        return x.AddDate(0, 0, -d)
    }

    return x
}

dateTime := "2023-01-31T15:51:00Z"
layout := "2006-01-02T15:04:00Z"

time, _ := time.Parse(layout, dateTime)

next1Month := AddMonth(time, 1) //  2023-02-28 15:51:00 +0000 UTC
next2Month := AddMonth(time, 2) // 2023-03-31 15:51:00 +0000 UTC

相关问题