time comparison fails for identical times using two different location objects?

Issue

I am expecting time.Now().In(location) objects to compare as identical if they are for the same moment, even though the location objects are different, as long as the location objects are created using the same name string.

Why doesn’t that expectation hold?

package main

import (
    "fmt"
    "time"

    "log"
)

func main() {
    const USPacificTimeZone = "US/Pacific"

    location, err := time.LoadLocation(USPacificTimeZone)
    if err != nil {
        log.Fatal(fmt.Sprintf("Couldn't load timezone: %v", err))
    }
    // Exactly the same as location above, just a new instance
    location2, err := time.LoadLocation(USPacificTimeZone)
    if err != nil {
        log.Fatal(fmt.Sprintf("Couldn't load timezone: %v", err))
    }

    now := time.Now()
    fmt.Printf("Times using same location object: %v\n",
        now.In(location) == now.In(location))
    // prints:  Times using same location object: true

    // Using (the identical) location2 causes the times to be different???
    fmt.Printf("Times using different location objects: %v\n",
        now.In(location) == now.In(location2))
    // prints:  Times using different location objects: false
}

Solution

Use the Equal method to compare instants in time:

fmt.Printf("Times using different location objects: %v\n",
    now.In(location).Equal(now.In(location2)))   // prints true

The Time type documentation describes the pitfalls of comparing Time values with ==:

Note that the Go == operator compares not just the time instant but also the Location and the monotonic clock reading. Therefore, Time values should not be used as map or database keys without first guaranteeing that the identical Location has been set for all values, which can be achieved through use of the UTC or Local method, and that the monotonic clock reading has been stripped by setting t = t.Round(0). In general, prefer t.Equal(u) to t == u, since t.Equal uses the most accurate comparison available and correctly handles the case when only one of its arguments has a monotonic clock reading.

Answered By – RedBlue

Answer Checked By – Candace Johnson (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.