Valentin
Valentin

Reputation: 1654

Time conversion issue in go language

I'm trying to understand the issue with time conversion in Go language. Here is code example:

package main

import (
    "fmt"
    "time"
)

func unix2Str(ts int64) string {
    const layout = "20060102"
    t := time.Unix(ts, 0)
    return t.Format(layout)
}

func unixTime(ts string) int64 {
    const layout = "20060102"
    t, err := time.Parse(layout, ts)
    if err != nil {
            fmt.Println(err)
            return 0
    }
    return t.Unix()
}
func main() {
    ts1 := "20110320"
    ts2 := "20110321"

    ut1 := unixTime(ts1)
    ut2 := unixTime(ts2)

    fmt.Println(ts1, ut1, unix2Str(ut1))
    fmt.Println(ts2, ut2, unix2Str(ut2))
}

It prints the following output:

20110320 1300579200 20110319
20110321 1300665600 20110320

But since I do the conversion from string format to Unix and reverse I would expect the same results for the date in string format. But it is not the case. In fact, the printed unix time 1300579200 is converted in python to original date I started with, e.g.

>>> time.strftime("%Y%m%d", time.gmtime(1300579200))
'20110320'

Is it a bug in Go code or am I missing something?

Upvotes: 5

Views: 787

Answers (1)

peterSO
peterSO

Reputation: 166825

It is because of the difference between your local time zone and UTC. Parse returned UTC time and Unix returned local time. For example,

package main

import (
    "fmt"
    "time"
)

func unix2Str(ts int64) string {
    const layout = "20060102"
    t := time.Unix(ts, 0)
    fmt.Println(t)
    return t.Format(layout)
}

func unixTime(ts string) int64 {
    const layout = "20060102"
    t, err := time.Parse(layout, ts)
    if err != nil {
        fmt.Println(err)
        return 0
    }
    fmt.Println(t)
    return t.Unix()
}

func main() {
    ts1 := "20110320"
    ts2 := "20110321"

    ut1 := unixTime(ts1)
    ut2 := unixTime(ts2)

    fmt.Println(ts1, ut1, unix2Str(ut1))
    fmt.Println(ts2, ut2, unix2Str(ut2))
}

Output:

2011-03-20 00:00:00 +0000 UTC
2011-03-21 00:00:00 +0000 UTC
2011-03-19 20:00:00 -0400 EDT
20110320 1300579200 20110319
2011-03-20 20:00:00 -0400 EDT
20110321 1300665600 20110320

func Parse

func Parse(layout, value string) (Time, error)

Parse parses a formatted string and returns the time value it represents. The layout defines the format by showing how the reference time, defined to be

Mon Jan 2 15:04:05 -0700 MST 2006

would be interpreted if it were the value; it serves as an example of the input format. The same interpretation will then be made to the input string.

In the absence of a time zone indicator, Parse returns a time in UTC.


func Unix

func Unix(sec int64, nsec int64) Time

Unix returns the local Time corresponding to the given Unix time, sec seconds and nsec nanoseconds since January 1, 1970 UTC.

Upvotes: 9

Related Questions