Golang: Get equivalent time in different timezone

I am trying to compare two times with different time zones and see if one is in front of the other. How can I do this in golang?

Note . Basically I would love to sfTime.Before(nyTime) == true

, but my example below would have sfTime.Before(nyTime) == false

. Suggestions on how to do this would be great.


For example, in this code ...

layout := "2006-01-02 15:04 MST"
sfTime, _ := time.Parse(layout, "2017-03-01 12:00 PDT")
nyTime, _ := time.Parse(layout, "2017-03-01 12:00 EDT")

fmt.Printf("Are these times equal? %v\n", sfTime.Equal(nyTime))

      

Prints:

Are these times equal? true

link to the site here .

Unintuitively, even if you set them to the same timezone, this only changes the timezone, not the value HH:mm

.

layout := "2006-01-02 15:04 MST"
sfTime, _ := time.Parse(layout, "2017-03-01 12:00 PDT")
nyTime, _ := time.Parse(layout, "2017-03-01 12:00 EDT")

// Set timezone to UTC
utcLocation, _ := time.LoadLocation("UTC")
sfTime = sfTime.In(utcLocation)
nyTime = nyTime.In(utcLocation)

// Timezones should not be equal, but they are
fmt.Printf("Are these times still equal? %v\n", sfTime.Equal(nyTime))
fmt.Printf("The New York Time: %v\n", nyTime)

      

Printing

Are these times still equal? true

New York time: 2017-03-01 12:00:00 +0000 UTC

Playground .

+3


source to share


3 answers


Don't use the Go Playground for timing. He works in a sandbox with a fake time:

About the playground

Go Playground is a web service that runs on golang.org servers. The service receives a Go program, compiles, links and runs the program inside the sandbox, then returns the result.

There are restrictions on the programs that can be performed in the playground.

On the playground, time begins at 2009-11-10 23:00:00 UTC (determining the significance of this date is an exercise for the reader). This makes it easier to cache programs by giving them deterministic output.

In addition, Go uses UTC at all times. Go Playground does not use the IANA Time Zone Database .

For example, for this program

package main

import (
    "fmt"
    "time"
)

func main() {
    layout := "2006-01-02 15:04 MST"
    sfTime, err := time.Parse(layout, "2017-03-01 12:00 PDT")
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(sfTime, sfTime.UTC())
    nyTime, err := time.Parse(layout, "2017-03-01 12:00 EDT")
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(nyTime, nyTime.UTC())
    fmt.Printf("Are these times equal? %v\n", sfTime.Equal(nyTime))
}

      

Exiting the Go Playground :

2017-03-01 12:00:00 +0000 PDT 2017-03-01 12:00:00 +0000 UTC
2017-03-01 12:00:00 +0000 EDT 2017-03-01 12:00:00 +0000 UTC
Are these times equal? true

      



For correct output, run the program with the Go compiler gc or gccgo:

$ go run equal.go
2017-03-01 12:00:00 +0000 PDT 2017-03-01 12:00:00 +0000 UTC
2017-03-01 11:00:00 -0500 EST 2017-03-01 16:00:00 +0000 UTC
Are these times equal? false

      

Using the Go compiler gc or gccgo, then sfTime.Before(nyTime) == true

:

package main

import (
    "fmt"
    "time"
)

func main() {
    layout := "2006-01-02 15:04 MST"
    sfTime, err := time.Parse(layout, "2017-03-01 12:00 PDT")
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(sfTime, sfTime.UTC())
    nyTime, err := time.Parse(layout, "2017-03-01 12:00 EDT")
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(nyTime, nyTime.UTC())
    fmt.Printf("Is the SF time before the NY time? %v\n", sfTime.Before(nyTime))
}

      

Output:

$ go run before.go
2017-03-01 12:00:00 +0000 PDT 2017-03-01 12:00:00 +0000 UTC
2017-03-01 11:00:00 -0500 EST 2017-03-01 16:00:00 +0000 UTC
Is the SF time before the NY time? true

      

Go's packet comparison methods time

( Equal

, Before

and After

) compare UTC values.

+2


source


I think this is a bug from play.golang.org, when I run it on my local machine, it returns Are these times equal? false

and Are these times still equal? false

.

As per the docs, this is the expected behavior (returning false):



// Equal messages about whether t and u represent the same time.

// Two times can be equal even if they are in different places.

// For example, 6:00 +0200 CEST and 4:00 UTC are equal.

Have you tried running it locally? The time on the playing court is set to a fixed point in time, so it may somehow be related to that.

+2


source


Your examples are working as intended, Equal point-in-time comparison . If you want to make sure the timezones are equal, you can do something liket1.Equal(t2) && t1.Location().String() == t2.Location().String()

From the docs with emphasis:

Each time is associated with it by a location, which is handled by the time representation when calculating, for example, format, hour, and year methods. Local, UTC and In Return methods are the time from a specific location. Changing the location in this way only changes the presentation; it does not change the point in time indicated and therefore does not affect the calculations described in the paragraphs earlier.

So, as far as I understand, whether you are executing time.Parse("... PDT")

, time.Parse("... EDT")

or sfTime.In(time.UTC)

, you always get the same point in time, the same number of seconds since 1970, and therefore call Equal

, Before

and After

on those time values ​​return the same result, regardless of Location

.

Update . I would just like to add to the selected answer that this is not playground specific, the original examples behave the same on my machine and if you look at the peterSO PDT output the time you can see is still treated as UTC. This behavior is described in the last paragraph of the Parse

documentation . (emphasis mine)

When analyzing time with a zone abbreviation such as MST, if the zone abbreviation has a certain offset at the current location, then the offset is used. The zone abbreviation "UTC" is recognized as UTC regardless of location. If the zone abbreviation is not known, Parse records the time as being in a fabricated location with the given zone abbreviation and zero offset. This choice means that such time can be parsed and reformatted with the same layout losslessly, but the exact moment used in the view will be different from the actual zone offset. To avoid such problems, prefers timing layouts that use a numeric zone offset or use ParseInLocation.

Here's an example using ParseInLocation

and numerical timezone offsets: https://play.golang.org/p/vY0muIvk5d

+1


source







All Articles