Golang : Get missing location after unmarshal binary and gob decode time.
Problem :
You loaded some time based data, found out that the time is missing location data and somehow screw up your time sensitive graph or summary report. How to fix this missing location problem?
Solution :
The time.Time
type has Location information before encoding/marshaling and because it is a pointer type. It won't be serialized properly as text data. To fix this problem, you need to use the time.Time.In()
function to set the decoded time back to the location that you want. The only weakness about this solution is that ... you need to know in advance which location (i.e America/New_York) when it was encoded. Perhaps the location can be stored separately in a field in the database or separate file.
NOTE : I've tried to solve the missing location data from gob decoded by getting the offset and translating to location... but it won't work without introducing bugs and without a constantly updated database.
Here you go!
package main
import (
"fmt"
"strings"
"time"
)
func main() {
loc, _ := time.LoadLocation("America/New_York")
t := time.Date(2015, 8, 6, 0, 0, 0, 0, loc)
fmt.Println("Time : ", t)
fmt.Println("Time Location : ", t.Location())
gobEncoded, err := t.GobEncode()
if err != nil {
fmt.Println(err)
}
fmt.Println("Gob encoded : ", gobEncoded)
// with GOB encoded(marshalled) data, can save to file(serialize)
// now, pretend that we loaded the GOB data
// we want to decode(unmarshal) the data
var gobTime time.Time
err = gobTime.GobDecode(gobEncoded)
if err != nil {
fmt.Println(err)
}
fmt.Println("Gob decoded time : ", gobTime)
fmt.Println("Gob decoded location(missing!) : ", gobTime.Location())
// because location is a pointer type (see http://golang.org/pkg/time/#Time.Location)
// it won't be encoded by Gob
// but you can translate it back to local time
fmt.Println("Gob decoded local : ", gobTime.Local().String())
// and convert back to target location
NYTime := gobTime.In(loc)
fmt.Println("Gob decoded back to America/New_York time : ", NYTime)
// a better solution is to use the time zone offset
// for our example is -0400
gobArray := strings.Fields(gobTime.String())
//fmt.Println(gobArray)
offset := gobArray[3]
fmt.Println("Offset time zone : ", offset)
// time.Parse() will not work, because
// in absence of a time zone indicator, Parse returns a time in UTC
// even translating the above offset to location is a challenge
// and the output below will be wrong
//longForm := "2015-08-06"
//newyorktime,_ := time.Parse(longForm, gobTime.String())
//fmt.Println(newyorktime)
}
Output :
Time : 2015-08-06 00:00:00 -0400 EDT
Time Location : America/New_York
Gob encoded : [1 0 0 0 14 205 84 210 192 0 0 0 0 255 16]
Gob decoded time : 2015-08-06 00:00:00 -0400 -0400
Gob decoded location(missing!) :
Gob decoded local : 2015-08-06 12:00:00 +0800 MYT
Gob decoded back to America/New_York time : 2015-08-06 00:00:00 -0400 EDT
Offset time zone : -0400
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+14.4k Golang : Get URI segments by number and assign as variable example
+21.8k Golang : Match strings by wildcard patterns with filepath.Match() function
+15.6k Golang : Read a file line by line
+13.5k Golang : Gin framework accept query string by post request example
+23.3k Find and replace a character in a string in Go
+12k Golang : How to display image file or expose CSS, JS files from localhost?
+9.7k Golang : Check if user agent is a robot or crawler example
+5.4k Golang : Frobnicate or tweaking a string example
+12k Golang : Flush and close file created by os.Create and bufio.NewWriter example
+19.9k Golang : How to get struct tag and use field name to retrieve data?
+12.7k Golang : Convert(cast) uintptr to string example
+10.6k Golang : Command line file upload program to server example