RFC3339 time parsing in golang

Shawn Rose picture Shawn Rose · Jun 20, 2016 · Viewed 21.9k times · Source

I'm pulling a timestamp from a datebase, it is using RFC3339 format but the timezone is missing. So when I try to compare the timestamps it will be off. How do I change dbtime to be Eastern time?

// time format
const
(
    RFC3339     = "2006-01-02T15:04:05Z07:00"
)

//now time
now := time.Now()
nowtime := now.Unix()

fmt.Println("Nowtime:", nowtime)
fmt.Println("Now:", now)

//time in db
fmt.Println("Dbtime string:", dbtime)
udbtime, err := time.Parse.EST(RFC3339,dbtime)
fmt.Println("RFC3339: " + RFC3339)
fmt.Println("dbtime parsed", udbtime)
fmt.Println("dbtime parsed unixtime", udbtime.Unix())

My output is

Nowtime: 1466443640
Now: 2016-06-20 13:27:20.963232824 -0400 EDT
Dbtime string: 2016-06-20T12:41:45.14Z
RFC3339: 2006-01-02T15:04:05Z07:00
dbtime parsed 2016-06-20 12:41:45.14 +0000 UTC
dbtime parsed unixtime 1466426505

Answer

JimB picture JimB · Jun 20, 2016

You could parse the timestamps using the defined time.RFC3339 like you've shown, and adjust them after the fact by adding the UTC offset so that they are correct in UTC.

udbtime = udbtime.Add(4*time.Hour)

This however requires that you check whether each time falls in EST or EDT to add the correct offset, unless you can assume they are all EDT.

A better way would be to use your own time format without a specific TZ offset (the Z isn't part of the time specification for parsing), and parse it with time.ParseInLocation.

This way you can account for the correct offset depending on whether the time would have been in EST or EDT.

https://play.golang.org/p/IrUnTwvlkk

RFC3339local := "2006-01-02T15:04:05Z"

loc, err := time.LoadLocation("America/New_York")
if err != nil {
    log.Fatal(err)
}

ts1 := "2016-06-20T12:41:45.14Z"
t1, _ := time.ParseInLocation(RFC3339local, ts1, loc)
fmt.Println(t1)
// prints: 2016-06-20 12:41:45.14 -0400 EDT

ts2 := "2016-01-20T12:41:45.14Z"
t2, _ = time.ParseInLocation(RFC3339local, ts2, loc)
fmt.Println(t2)
// prints: 2016-01-20 12:41:45.14 -0500 EST