英文:
Rest one month in a date golang
问题
我正在尝试在Golang中将一个日期减去一个月,我有以下关于三月和二月的示例代码:
date := time.Date(2023, time.March, 31, 0, 0, 0, 0, time.UTC)
然后我执行了以下操作:
period := date.AddDate(0, -1, 0)
但程序给出的结果是:
原始日期:2023-03-31 00:00:00 +0000 UTC
减去一个月后的日期:2023-03-03 00:00:00 +0000 UTC
而我期望的结果是:
2023-02-28 00:00:00 +0000 UTC
同时,我希望这个减去一个月的操作对每个月都能动态地适用。
谢谢。
英文:
Im trying to rest a month in a date in golang i have this example for march an February:
date := time.Date(2023, time.March, 31, 0, 0, 0, 0, time.UTC)
then a make this:
period := date.AddDate(0, -1, -0)
but the program give me:
> original date: 2023-03-31 00:00:00 +0000 UTC
>
> date after rest: 2023-03-03 00:00:00 +0000 UTC
And I expect:
> 2023-02-28 00:00:00 +0000 UTC
at the same time I want that this rest work for every month dynamically.
Thanks.
答案1
得分: 2
正如自动转换所带来的困扰一样,你也可以利用它。
关键在于如何获取上个月的天数。
// 因为没有0号这一天,所以它表示上个月的最后一天
totDay := time.Date(y, m, 0, 0, 0, 0, 0, time.UTC).Day()
完整的代码如下:
package main
import (
"fmt"
"time"
)
func previousMouth(t time.Time) time.Time {
y, m, d := t.Date()
curTotDay := time.Date(y, m+1, 0, 0, 0, 0, 0, time.UTC).Day()
totDay := time.Date(y, m, 0, 0, 0, 0, 0, time.UTC).Day()
if d == curTotDay {
d = totDay
}
return time.Date(y, m-1, d, 0, 0, 0, 0, time.UTC)
}
func main() {
date := time.Date(2023, time.March, 31, 0, 0, 0, 0, time.UTC)
fmt.Println(previousMouth(date))
}
在线运行:goplayground。
英文:
Just as the automatically transform that comes with go annoys you, you could also take advantage of this.
The trick is how to get the number of days in the previous month.
// as there is no 0 day, it means the last day of the previous mouth
totDay := time.Date(y, m, 0, 0, 0, 0, 0, time.UTC).Day()
The complete code is as follows:
package main
import (
"fmt"
"time"
)
func previousMouth(t time.Time) time.Time {
y, m, d := t.Date()
curTotDay := time.Date(y, m+1, 0, 0, 0, 0, 0, time.UTC).Day()
totDay := time.Date(y, m, 0, 0, 0, 0, 0, time.UTC).Day()
if d == curTotDay {
d = totDay
}
return time.Date(y, m-1, d, 0, 0, 0, 0, time.UTC)
}
func main() {
date := time.Date(2023, time.March, 31, 0, 0, 0, 0, time.UTC)
fmt.Println(previousMouth(date))
}
Run it online: goplayground.
答案2
得分: 0
正如其他人在评论中提到的,你不能准确地回到3月31日的前一个月。你会得到2月31日,但这个日期不存在,会被规范化为3月3日。
你可以回到上个月的最后一天,但如果你从3月28日、3月29日、3月30日或3月31日开始,结果是一样的。
但如果这是你想要的,你可以回到(或前进)任意数量的月份,同时将日期限制在该月的天数范围内。
func firstDayOfMonth(date time.Time) time.Time {
return date.AddDate(0, 0, -date.Day()+1)
}
func daysInMonth(date time.Time) int {
return date.AddDate(0, 1, -date.Day()).Day()
}
func AddMonthsClipped(date time.Time, months int) time.Time {
firstDate := firstDayOfMonth(date)
firstAdded := firstDate.AddDate(0, months, 0)
addDays, maxDays := date.Day(), daysInMonth(firstAdded)
if addDays > maxDays {
addDays = maxDays
}
return firstAdded.AddDate(0, 0, addDays-1)
}
func main() {
date := time.Date(2023, time.March, 31, 0, 0, 0, 0, time.UTC)
fmt.Println(AddMonthsClipped(date, -1))
}
Go Playground: https://go.dev/play/p/JEihMdM0CHe
英文:
As others have mentioned in the comments, you cannot go back exactly one month from 31 March. You would end up at 31 February, but that date doesn't exist and is normalised to 3 March.
You can go back to the last day of the previous month, but you would get the same result if you started at 28 March, 29 March, 30 March or 31 March.
But if that is what you want, you can go back (or forward) any number of months, while clipping the day to remain within the number of days in that month.
func firstDayOfMonth(date time.Time) time.Time {
return date.AddDate(0, 0, -date.Day()+1)
}
func daysInMonth(date time.Time) int {
return date.AddDate(0, 1, -date.Day()).Day()
}
func AddMonthsClipped(date time.Time, months int) time.Time {
firstDate := firstDayOfMonth(date)
firstAdded := firstDate.AddDate(0, months, 0)
addDays, maxDays := date.Day(), daysInMonth(firstAdded)
if addDays > maxDays {
addDays = maxDays
}
return firstAdded.AddDate(0, 0, addDays-1)
}
func main() {
date := time.Date(2023, time.March, 31, 0, 0, 0, 0, time.UTC)
fmt.Println(AddMonthsClipped(date, -1))
}
Go Playground: https://go.dev/play/p/JEihMdM0CHe
答案3
得分: 0
我找到了答案:
package main
import (
"fmt"
"time"
)
func main() {
date := time.Date(2023, time.March, 31, 0, 0, 0, 0, time.UTC)
year, month, _ := date.Date()
endOfLastMonth := time.Date(year, month, 0, 0, 0, 0, 0, date.Location())
fmt.Println("本月:", date)
fmt.Println("上个月:", endOfLastMonth)
}
这是代码的运行结果:https://go.dev/play/p/iTDFgtdOT9y
在处理日期的过程中,我做出了这个结果。谢谢大家。
英文:
I found the answer:
package main
import (
"fmt"
"time"
)
func main() {
date := time.Date(2023, time.March, 31, 0, 0, 0, 0, time.UTC)
year, month, _ := date.Date()
endOfLastMonth := time.Date(year, month, 0, 0, 0, 0, 0, date.Location())
fmt.Println("This month: ", date)
fmt.Println("Lasth Month: ", endOfLastMonth)
}
Here the playground: https://go.dev/play/p/iTDFgtdOT9y
After working and working with the date, i made this. Thanks you all
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论