2016-04-07 5 views
12

Im folgenden Code,Warum erhalte ich falsche Antworten in Datumsfunktion in golang

  • t1 ist die Zeit von 62 Tagen nach dem Datum 1970.01.01 (yy/mm/dd)
  • t2 ist an der Zeit von 63 Tagen nach dem Datum 1970.01.01 (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) 
} 

Wenn t1:

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

Ich erwarte, dass t2 sein:

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

Aber der Ausgang ist:

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

Was ist der Grund dafür?

Antwort

11

t1 ist die Zeit von 62 Tagen nach dem Datum 1970.01.01 (yy/mm/dd) t2 ist die Zeit von 63 Tagen nach dem Datum 1970.01.01 (yy/mm/dd)

Dies ist nicht wahr. t1 ist die Zeit 1970 Jahre, 1 Monat und 1 Tag nach was auch immer time.Date(0, 0, 62, 0, 0, 0, 0, time.UTC) bedeutet.

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)) 

gibt uns:

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

Das ist völlig falsch. UTC ist für keine Daten vor 1972 definiert, der Gregorianische Kalender beginnt nicht vor 1582 und es gab nie ein Jahr 0. Wenn ich all das ignoriere, sehe ich nicht, wie der 63. Tag eines Jahres als 31. Januar interpretiert werden könnte. aber lass uns trotzdem gehen.

Fügen wir Dinge zum ersten Zeitstempel hinzu: fügen Sie 1970 hinzu, erhalten wir 1970-01-31. Fügen Sie einen Monat hinzu, erhalten wir 1970-02-31. Aber 1970-02-31 ist kein gültiges Datum. So ist es bis zum 3. März normalisiert. 1970 war kein Schaltjahr, der Februar hatte 28 Tage, also ist der 29. Februar der 1. März, der 30. Februar der 2. März, der 31. Februar der 3. März. Fügen Sie einen Tag dem 1970-03-03 hinzu und wir erhalten 1970-03-04.

Der zweite Zeitstempel analysiert bereits den 1. Februar. Fügen Sie einen Monat hinzu und wir bekommen den 1. März, fügen einen Tag hinzu und wir bekommen den 2. März.

Dies geschieht, wenn Sie Monate zu Zeitstempeln hinzufügen. Ein Monat ist keine sehr gut definierte Dauer. Die Bibliothek versucht also, clever zu sein und das bringt unerwartete Ergebnisse.

Btw. Aus irgendeinem Grund: fmt.Println(time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC)) wird als -0001-11-30 00:00:00 +0000 UTC interpretiert. Keine Ahnung warum. Ist nicht wirklich wichtig, da Jahr 0 und Monat 0 nicht existieren. Aber es erklärt, warum die früheren Zeitstempel am 31. Januar und 1. Februar enden.

Es gibt keinen Grund für AddDate, um Dinge in dieser Reihenfolge hinzuzufügen. Soweit ich es beurteilen kann, ist es nicht dokumentiert. Es hätte auch den Tag zuerst, dann den Monat, dann die Jahre hinzugefügt. Versuchen Sie Folgendes auszuführen:

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)) 
Verwandte Themen