Where are my 27 seconds?

Since Unix time does not take leap seconds into account, and standard UTC does, I would expect to see a difference of 27 seconds (the leap seconds since epoch) when I go back and forth in such code, but it give me back exactly the same date/time.
The time.Now() is synchronized with the official time, that is UTC.

There seems to be a thing I did not catch in the Go handling of time.

nn:=time.Now()
fmt.Println(nn)
fmt.Println(time.Now().UTC())
fmt.Println(nn.Unix())
rfc:=nn.Format(time.RFC3339)
fmt.Println(rfc)
thetime, e := time.Parse(time.RFC3339, rfc)
if e != nil {
panic(“Can’t parse time format”)
}
epoch := thetime.Unix()
fmt.Println(epoch)

I’m not certain, but I suspect time.Time.Unix doesn’t handle leap seconds because Google doesn’t use leap seconds.

time.Now is the unix time adjusted with leap seconds. This is the reason you don’t see a difference.

Your assumption that the unix time does not include the leap seconds is wrong. This time thing and the leap seconds is indeed confusing.

There is a go issue about leap seconds which lead on to this issue where exactly what kind of second go uses is defined

This got boiled down to this in the docs (the bolded part being the addition)

The calendrical calculations always assume a Gregorian calendar, with no leap seconds.

So it is complicated but I like the summary from that thread “Go does it like Linux”!

Thank you for your answer. It “clarifies” where the problem is.
For those who are interested, here is an example showing the error.
func main() {
epoch:=time.Date(1970,1,1,0,0,0,0,time.UTC)
fmt.Printf(" epoch en date: %v\n",epoch)
uepoch:=int64(epoch.Unix())
fmt.Printf(" epoch en unix timestamp: %v\n",uepoch)
startprocess :=time.Date(2008,12,31,23,59,59,0,time.UTC)
fmt.Printf(“process start at: %v (correct time)\n”,startprocess)
ustartprocess :=startprocess.Unix()
fmt.Printf(“unix timestamp of starting process: %v\n”,ustartprocess)
intendingprocess:=ustartprocess+4
fmt.Printf(“process end timestamp: %v,\n”,intendingprocess)
endingdate:=time.Unix(intendingprocess,0)
fmt.Printf(“endingdate: %v\n”,endingdate)

fmt.Println(time.Now())

start := time.Date(2008, 12, 31, 23, 59, 59, 0, time.UTC)
end := time.Date(2009, 1, 1, 0, 0, 3, 0, time.UTC)

difference := end.Sub(start)
fmt.Printf("difference = %v\n", difference)

}

1 Like

Thank you, actually the confusion (for me) is deeper than that. If you look at the example in my other reply it shows there is a problem with mixing monotonic and wall clock, and this leads to errors. If I add the actual number of seconds to a process around the leap second, I find my 27 seconds.