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
+18.5k Golang : convert int to string
+26.1k Golang : Calculate future date with time.Add() function
+20.9k Golang : Create and resolve(read) symbolic links
+8.8k Golang : io.Reader causing panic: runtime error: invalid memory address or nil pointer dereference
+8.3k Android Studio : Import third-party library or package into Gradle Scripts
+10.4k Golang : Flip coin example
+9.3k Golang : Read file with ioutil
+23.6k Golang : Use regular expression to validate domain name
+6.3k Golang : How to determine if request or crawl is from Google robots
+6.6k Golang : Get expvar(export variables) to work with multiplexer
+17.4k Golang : Upload/Receive file progress indicator
+16.6k Golang : Set up source IP address before making HTTP request