Prior to September 1, 1906, your time zone difference was UTC-7:33:52. json.Unmarshal
is just using the 7:33 in the marshaled text for the offset, instead of the correct value of 7:33:52, so the time.Time
value it calculates is off by 52 seconds. But your time.Local
implementation seems to be getting it right (to the extent we can describe backdating time zone differences to year 1 as "right") and subtracting the full 7:33:52 from the time.Time
value, resulting in the difference you're seeing.
If you output:
fmt.Printf("Time A: %+v, Time B: %+v
", timeA.UTC(), timeB.UTC())
with your current code you should see that the UTC time for timeB
is getting set to 15:33:00 after unmarshaling, whereas the UTC time for timeA
is getting set to 15:33:52. I suspect if you include a year after 1906 in your time string you'll see this 52 seconds difference disappear.
For example:
package main
import (
"encoding/json"
"fmt"
"log"
"time"
)
func main() {
zone, err := time.LoadLocation("America/Edmonton")
if err != nil {
log.Fatalf("%v", err)
}
for _, timestring := range []string{
"01 02 1905 8:00",
"01 02 1907 8:00",
} {
timeA, err := time.ParseInLocation("01 02 2006 15:04", timestring, zone)
if err != nil {
log.Fatalf("%v", err)
}
jBytes, _ := json.Marshal(timeA)
var timeB time.Time
json.Unmarshal(jBytes, &timeB)
fmt.Printf("Time string: %s
", timestring)
fmt.Printf("Time A: %+v, Time B: %+v
", timeA, timeB)
fmt.Printf("Time A: %+v, Time B: %+v
", timeA.UTC(), timeB.UTC())
fmt.Printf("Time A: %+v, Time B: %+v
", timeA.In(zone), timeB.In(zone))
fmt.Printf("Diff: %s
", timeA.Sub(timeB))
fmt.Printf("Marshaled: %s
", string(jBytes))
}
}
outputs:
paul@mac:got$ ./got
Time string: 01 02 1905 8:00
Time A: 1905-01-02 08:00:00 -0733 LMT, Time B: 1905-01-02 08:00:00 -0733 -0733
Time A: 1905-01-02 15:33:52 +0000 UTC, Time B: 1905-01-02 15:33:00 +0000 UTC
Time A: 1905-01-02 08:00:00 -0733 LMT, Time B: 1905-01-02 07:59:08 -0733 LMT
Diff: 52s
Marshaled: "1905-01-02T08:00:00-07:33"
Time string: 01 02 1907 8:00
Time A: 1907-01-02 08:00:00 -0700 MST, Time B: 1907-01-02 08:00:00 -0700 -0700
Time A: 1907-01-02 15:00:00 +0000 UTC, Time B: 1907-01-02 15:00:00 +0000 UTC
Time A: 1907-01-02 08:00:00 -0700 MST, Time B: 1907-01-02 08:00:00 -0700 MST
Diff: 0s
Marshaled: "1907-01-02T08:00:00-07:00"
paul@mac:got$
showing that the 52 second difference is there for 1905, but not for 1907 after the time zone difference changed to a straight UTC-7:00:00.
Short answer: marshaling to and unmarshaling from json by default appears unable to correctly handle seconds in time zone offsets, because no seconds appear in the offset in the marshaled string and this is the only time zone information json.Unmarshal
has available to it.
For sure there is no referencing of clocks, remote or otherwise, in any of this code - it's just manipulating values.