Why I am getting wrong answers in Date function in golang

时间:2016-04-07 10:25:31

标签: go

In the following code,

  • t1 is time on 62 days after the date 1970/1/1 (yy/mm/dd)
  • t2 is time on 63 days after the date 1970/1/1 (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)
}

If t1 is:

Time1: 1970-03-04 00:00:00 +0000 UTC

I expect t2 to be:

Time2: 1970-03-05 00:00:00 +0000 UTC

But the output is:

Time2: 1970-03-02 00:00:00 +0000 UTC

What is the reason for this?

1 个答案:

答案 0 :(得分:11)

  

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

事实并非如此。 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

这是完全错误的。对于1972年之前的任何日期,UTC都没有定义,公历从1582年开始并且从未有过任何一年。忽略这一切,我不知道一年中的第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))