In the following code,
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?
The specific date Go uses for date and time layouts in string formatting is 01/02 03:04:05PM '06 -0700 .
Using the “time. Now()” function you can get the date and time in the “yyyy-mm-dd hh:mm:ss. milliseconds timezone” format. This is simplest way for getting the date and time in golang.
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)
This is not true. t1
is the time 1970 years, 1 month and 1 day after whatever time.Date(0, 0, 62, 0, 0, 0, 0, time.UTC)
means.
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))
gives us:
0000-01-31 00:00:00 +0000 UTC
0000-02-01 00:00:00 +0000 UTC
This is completely wrong. UTC isn't defined for any dates before 1972, the Gregorian calendar doesn't start until 1582 and there was never any year 0. Ignoring all that, I don't see how day 63 of a year could be interpreted as January 31st, but let's go with it anyway.
Let's add things to the first timestamp: add 1970, we get 1970-01-31. Add a month, we get 1970-02-31. But 1970-02-31 isn't a valid date. So it is normalized to March 3rd. 1970 wasn't a leap year, February had 28 days, so Feb 29 is Mar 1, Feb 30 is Mar 2, Feb 31 is Mar 3. Add one day to 1970-03-03 and we get 1970-03-04.
The second timestamp already parses to February 1st. Add a month and we get March 1st, add a day and we get March 2nd.
This is what happens when you add months to timestamps. A month is not a very well defined duration. So the library tries to be clever for you and that gets you unexpected results.
Btw. for some reason: fmt.Println(time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC))
is interpreted as -0001-11-30 00:00:00 +0000 UTC
. No idea why. Doesn't really matter since year 0 and month 0 don't exist. But it explains why the earlier timestamps end up at Jan 31st and Feb 1st.
There is no reason for AddDate to add things in this order. It is not documented as far as I can see. It could as well have added the day first, then the month, then the years. Try running this:
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))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With