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
+24.1k Golang : How to print rune, unicode, utf-8 and non-ASCII CJK(Chinese/Japanese/Korean) characters?
+7.1k Android Studio : How to detect camera, activate and capture example
+5.2k Golang *File points to a file or directory ?
+14.1k Golang : How to check if your program is running in a terminal
+19.5k Golang : Accept input from user with fmt.Scanf skipped white spaces and how to fix it
+15.2k Golang : Force download file example
+9.9k Golang : Detect number of faces or vehicles in a photo
+15.9k Golang : convert string or integer to big.Int type
+10.2k Swift : Convert (cast) String to Integer
+14k Golang : Recombine chunked files example
+17.4k Golang : Read data from config file and assign to variables
+11.6k Golang : Convert(cast) bigint to string