Preface
A week ago, I had a small chat with my friend over some Slack workspace, something like:
friend: "Does anyone know why
time.minWall
defaults to 1885?"
me: "No idea, maybe it's from the year in Back To The Future 3?"
At that time, I was almost joking but I had no idea why it was set to 1885 neither. Though the fact behind it does not have anything to do with my daily coding in Go, I couldn't help asking the behind-the-scene. I asked my peer Gophers in the team chat, but it seemed no one there couldn't reach the clues for the decision.
Finally, I sent an email to Russ Cox (@_rsc) directly to know the background for the decision.
time.minWall
A const value time.minWall
is set to 1885.
const (
hasMonotonic = 1 << 63
maxWall = wallToInternal + (1<<33 - 1) // year 2157
minWall = wallToInternal // year 1885
nsecMask = 1<<30 - 1
nsecShift = 30
)
This is the constant value that defines the epoch of values in time package. We often use UNIX epoch (i.e. 00:00:00 UTC on 1st January 1970), but it is just one epoch out of a couple of standards or implementations to express datetime values, and of course Go is a multi platform language, so the epoch in Go need to cover all those platforms.
Russ Cox had given comments on Go's epoch publicly in the following places. The first one is on the GitHub issue thread:
OK, this is checked in for Go 1.9. I moved the internal epoch to 1885 (max year 2157) to avoid any possible problem with NTP-epoch-derived times. I also adjusted the design doc to reflect this change and some minor encoding changes.
But this comment only mentions why and when they moved the internal epoch to 1885, but not why they didn't to any other years, such as 1900.
The second one is the proposal doc for the move of the internal epoch.
Unix-based systems often use 1970, and Windows-based systems often use 1980. We are unaware of any systems using earlier default wall times, but since the NTP protocol epoch uses 1900, it seemed more future-proof to choose a year before 1900.
Okay, still the rationale supports any years before 1900, not specifically 1885. I was almost sure that the year is derived from Back To The Future 3, but I wanted 100% sure for it and I reached out to the person who only knows the decision behind it; I sent an email to Russ to ask the reason. He gave a response within a day (it's super quick, considering timezone difference between EDT and JST) saying:
Yes, people talked me into moving it back before 1900, and 1885 was the obvious choice due to its historical significance to Hill Valley, California. :-)
I knew it!! Also, it was more than happy that I could get the true answer from who made the decision.
http.aLongTimeAgo
While I appreciated the answer from Russ, it was not the end of the story. There was the another line in Russ' reply.
See also http.aLongTimeAgo, which is now sadly set to time.Unix(1, 0) but used to be time.Unix(233431200, 0).
In Go 1.14.5, as he says, it's set to time.Unix(1, 0)
.
// aLongTimeAgo is a non-zero time, far in the past, used for
// immediate cancellation of network operations.
var aLongTimeAgo = time.Unix(1, 0)
So let's confirm its original value when it was introduced to the source code. You can find it in Go 1.8.
// aLongTimeAgo is a non-zero time, far in the past, used for
// immediate cancelation of network operations.
var aLongTimeAgo = time.Unix(233431200, 0)
Let's convert the UNIX time to human readable format. Of course, Go gives super easy way to do it.
package main
import (
"fmt"
"time"
)
func main() {
pdt, _ := time.LoadLocation("America/Los_Angeles")
t := time.Unix(233431200, 0).In(pdt)
fmt.Println(t)
}
The result is:
1977-05-25 11:00:00 -0700 PDT
We got 2 hints: "A Long Time Ago" and "May 25th, 1977". What these 2 lead to is...
Of course, nothing but Star Wars: Episode IV. It was released on May 25th, 1977 (Wikipedia)
How this value is used in Go package is to force cancelling existing connections immediately by giving deadlines in past time, such as:
cr.conn.rwc.SetReadDeadline(aLongTimeAgo)
Some people reacted on the changes when the value was changed to time.Unix(1, 0)
. I love to see these kinds of comments; those fun chats occasionally happen in changelists.
Acknowledgement
- Russ Cox: Thank you for replying to my question and the additional information. Also, thank you for the approval to share this publicly. Quoting his comment:
Feel free. No secrets here.
Chris Broadfoot and Valentin Deleplace: Thank you for finding out the clues together on the group chat.
mattn: Thank you for letting me know the GitHub thread where people reacted on the value.
Note
This entry was originally posted to my Japanese blog on July 17th.
Top comments (3)
This made me chuckle quite a bit. Thanks for sharing this!
This is really interesting. It makes me want to code ๐. Thank you for sharing ๐
I like things like this! Thanks for sharing ๐