Convert UTC to "local" time in Go

How can I convert UTC time to local time?

I created a map with a difference in UTC for all countries where I need local time. Then I add this difference as the duration to the current time (UTC) and print the result in the hope of the local time of this particular country.

For some reason, the result is incorrect. For example, with Hungary, the difference is one hour. Any ideas why I am getting the wrong results?

package main import "fmt" import "time" func main() { m := make(map[string]string) m["Hungary"] = "+01.00h" offSet, err := time.ParseDuration(m["Hungary"]) if err != nil { panic(err) } t := time.Now().UTC().Add(offSet) nice := t.Format("15:04") fmt.Println(nice) } 
+14
timezone time go timezoneoffset timezone-offset
source share
3 answers

Keep in mind that the playground has a time set for 2009-11-10 23:00:00 +0000 UTC , so it works.

The correct way is to use time.LoadLocation , although here is an example:

 var countryTz = map[string]string{ "Hungary": "Europe/Budapest", "Egypt": "Africa/Cairo", } func timeIn(name string) time.Time { loc, err := time.LoadLocation(countryTz[name]) if err != nil { panic(err) } return time.Now().In(loc) } func main() { utc := time.Now().UTC().Format("15:04") hun := timeIn("Hungary").Format("15:04") eg := timeIn("Egypt").Format("15:04") fmt.Println(utc, hun, eg) } 
+22
source share

Your approach is wrong. A country can have several time zones, for example, the USA and Russia. Due to daylight saving time (DST), the time zone may have more than once, for example, in Hungary. Hungary is UTC +1: 00, as well as UTC + 2: 00 for DST.

For each location where you want local time for a given UTC time, use the IANA time zone location (tzdata). For example,

 package main import ( "fmt" "time" ) func main() { utc := time.Now().UTC() fmt.Println(utc) local := utc location, err := time.LoadLocation("Europe/Budapest") if err == nil { local = local.In(location) } fmt.Println("UTC", utc.Format("15:04"), local.Location(), local.Format("15:04")) local = utc location, err = time.LoadLocation("America/Los_Angeles") if err == nil { local = local.In(location) } fmt.Println("UTC", utc.Format("15:04"), local.Location(), local.Format("15:04")) } 

Output:

 2014-08-14 23:57:09.151377514 +0000 UTC UTC 23:57 Europe/Budapest 01:57 UTC 23:57 America/Los_Angeles 16:57 

Literature:

IANA Time Zone Database

tz database

tz database time zones

Timezone

Time in Hungary

+11
source share

Save yourself from clutter in certain areas, use the location "Local". Here is a complete and practical example of local and UTC conversion:

 package main import ( "fmt" "log" "time" ) const ( dateTimeFormat = "2006-01-02 15:04 MST" dateFormat = "2006-01-02" timeFormat = "15:04" ) // A full cycle example of receiving local date and time, // handing off to a database, retrieving as UTC, and formatting as local datetime // This should be good in *any* timezone func main() { // If using a form for entry, I strongly suggest a controlled format input like // <input type="date" ... > and <input type="time" ... > locallyEnteredDate := "2017-07-16" locallyEnteredTime := "14:00" // Build a time object from received fields (time objects include zone info) // We are assuming the code is running on a server that is in the same zone as the current user zone, _ := time.Now().Zone() // get the local zone dateTimeZ := locallyEnteredDate + " " + locallyEnteredTime + " " + zone dte, err := time.Parse(dateTimeFormat, dateTimeZ) if err != nil { log.Fatal("Error parsing entered datetime", err) } fmt.Println("dte:", dte) // dte is a legit time object // Perhaps we are saving this in a database. // A good database driver should save the time object as UTC in a time with zone field, // and return a time object with UTC as zone. // For the sake of this example, let assume an object identical to `dte` is returned // dte := ReceiveFromDatabase() // Convert received date to local. // Note the use of the convenient "Local" location https://golang.org/pkg/time/#LoadLocation. localLoc, err := time.LoadLocation("Local") if err != nil { log.Fatal(`Failed to load location "Local"`) } localDateTime := dte.In(localLoc) fmt.Println("Date:", localDateTime.Format(dateFormat)) fmt.Println("Time:", localDateTime.Format(timeFormat)) } 
+2
source share

All Articles