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

Jsm*_*ith 12 go

在以下代码中,

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

package main

import (
    "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)
}
Run Code Online (Sandbox Code Playgroud)

如果t1是:

Time1: 1970-03-04 00:00:00 +0000 UTC
Run Code Online (Sandbox Code Playgroud)

我希望t2是:

Time2: 1970-03-05 00:00:00 +0000 UTC
Run Code Online (Sandbox Code Playgroud)

但输出是:

Time2: 1970-03-02 00:00:00 +0000 UTC
Run Code Online (Sandbox Code Playgroud)

这是什么原因?

Art*_*Art 11

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

这不是真的.t1是无论什么time.Date(0, 0, 62, 0, 0, 0, 0, time.UTC)方式,1970年,1个月和1天的时间.

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))
Run Code Online (Sandbox Code Playgroud)

给我们:

0000-01-31 00:00:00 +0000 UTC
0000-02-01 00:00:00 +0000 UTC
Run Code Online (Sandbox Code Playgroud)

这是完全错误的.没有为1972年之前的任何日期定义UTC,公历直到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)) 
Run Code Online (Sandbox Code Playgroud)