为了账号安全,请及时绑定邮箱和手机立即绑定

为什么我在 golang 的 Date 函数中得到错误答案

为什么我在 golang 的 Date 函数中得到错误答案

Go
FFIVE 2022-01-04 09:58:25
在以下代码中,t1 是 1970/1/1 (yy/mm/dd) 日期后 62 天的时间t2 是 1970/1/1 (yy/mm/dd) 日期后 63 天的时间package mainimport (    "fmt"    "time")func main() {    t1 := time.Date(0, 0, 62, 0, 0, 0, 0, time.UTC).AddDate(1970, 1, 1)    t2 := time.Date(0, 0, 63, 0, 0, 0, 0, time.UTC).AddDate(1970, 1, 1)    fmt.Println("Time1:  ", t1)    fmt.Println("Time2:  ", t2)}如果 t1 是:Time1: 1970-03-04 00:00:00 +0000 UTC我希望 t2 是:Time2: 1970-03-05 00:00:00 +0000 UTC但输出是:Time2: 1970-03-02 00:00:00 +0000 UTC这是什么原因?
查看完整描述

1 回答

?
慕勒3428872

TA贡献1848条经验 获得超6个赞

t1 是日期 1970/1/1 (yy/mm/dd) 之后 62 天的时间 t2 是日期 1970/1/1 (yy/mm/dd) 之后 63 天的时间


这不是真的。t1是 1970 年之后的 1 个月零 1 天time.Date(0, 0, 62, 0, 0, 0, 0, time.UTC)。


fmt.Println(time.Date(0, 0, 62, 0, 0, 0, 0, time.UTC))

fmt.Println(time.Date(0, 0, 63, 0, 0, 0, 0, time.UTC))

给我们:


0000-01-31 00:00:00 +0000 UTC

0000-02-01 00:00:00 +0000 UTC

这是完全错误的。UTC 没有为 1972 年之前的任何日期定义,公历直到 1582 年才开始,而且从来没有任何年份 0。忽略所有这些,我不明白如何将一年中的第 63 天解释为 1 月 31 日,但无论如何,让我们继续吧。


让我们向第一个时间戳添加内容:添加 1970,我们得到 1970-01-31。添加一个月,我们得到 1970-02-31。但是 1970-02-31 不是有效日期。所以它被标准化到3月3日。1970年不是闰年,2月有28天,所以2月29日是3月1日,2月30日是3月2日,2月31日是3月3日。在1970-03-03加上一天,我们得到1970-03-04。


第二个时间戳已解析为 2 月 1 日。加上一个月,我们得到 3 月 1 日,加上一天,我们得到 3 月 2 日。


这就是将月份添加到时间戳时会发生的情况。一个月不是一个非常明确的持续时间。因此,库会尝试为您变得聪明,这会给您带来意想不到的结果。


顺便提一句。出于某种原因:fmt.Println(time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC))被解释为-0001-11-30 00:00:00 +0000 UTC。不知道为什么。并不重要,因为第 0 年和第 0 个月不存在。但这解释了为什么较早的时间戳在 1 月 31 日和 2 月 1 日结束。


AddDate 没有理由按此顺序添加内容。据我所知,它没有记录。它也可以先添加日期,然后添加月份,然后添加年份。尝试运行这个:


fmt.Println(time.Date(2015, 1, 31, 0, 0, 0, 0, time.UTC).AddDate(1, 0, 0).AddDate(0, 1, 0))

fmt.Println(time.Date(2015, 1, 31, 0, 0, 0, 0, time.UTC).AddDate(0, 1, 0).AddDate(1, 0, 0)) 



查看完整回答
反对 回复 2022-01-04
  • 1 回答
  • 0 关注
  • 722 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信