How to parse unix timestamp to time.Time

GoTimeUnix Timestamp

Go Problem Overview


I'm trying to parse an Unix timestamp but I get out of range error. That doesn't really makes sense to me, because the layout is correct (as in the Go docs):

package main

import "fmt"
import "time"

func main() {
    tm, err := time.Parse("1136239445", "1405544146")
    if err != nil{
        panic(err)
    }

    fmt.Println(tm)
}

Playground

Go Solutions


Solution 1 - Go

The time.Parse function does not do Unix timestamps. Instead you can use strconv.ParseInt to parse the string to int64 and create the timestamp with time.Unix:

package main

import (
	"fmt"
	"time"
	"strconv"
)

func main() {
	i, err := strconv.ParseInt("1405544146", 10, 64)
	if err != nil {
		panic(err)
	}
	tm := time.Unix(i, 0)
	fmt.Println(tm)
}

Output:

2014-07-16 20:55:46 +0000 UTC

Playground: http://play.golang.org/p/v_j6UIro7a

Edit:

Changed from strconv.Atoi to strconv.ParseInt to avoid int overflows on 32 bit systems.

Solution 2 - Go

You can directly use time.Unix function of time which converts the unix time stamp to UTC

package main

import (
  "fmt"
  "time"
)


func main() {
	unixTimeUTC:=time.Unix(1405544146, 0) //gives unix time stamp in utc 

    unitTimeInRFC3339 :=unixTimeUTC.Format(time.RFC3339) // converts utc time to RFC3339 format

	fmt.Println("unix time stamp in UTC :--->",unixTimeUTC)
    fmt.Println("unix time stamp in unitTimeInRFC3339 format :->",unitTimeInRFC3339)
}

Output

unix time stamp in UTC :---> 2014-07-16 20:55:46 +0000 UTC
unix time stamp in unitTimeInRFC3339 format :----> 2014-07-16T20:55:46Z

Check in Go Playground: https://play.golang.org/p/5FtRdnkxAd

Solution 3 - Go

Sharing a few functions which I created for dates:

Please note that I wanted to get time for a particular location (not just UTC time). If you want UTC time, just remove loc variable and .In(loc) function call.

func GetTimeStamp() string {
     loc, _ := time.LoadLocation("America/Los_Angeles")
     t := time.Now().In(loc)
     return t.Format("20060102150405")
}
func GetTodaysDate() string {
    loc, _ := time.LoadLocation("America/Los_Angeles")
    current_time := time.Now().In(loc)
    return current_time.Format("2006-01-02")
}

func GetTodaysDateTime() string {
    loc, _ := time.LoadLocation("America/Los_Angeles")
    current_time := time.Now().In(loc)
    return current_time.Format("2006-01-02 15:04:05")
}

func GetTodaysDateTimeFormatted() string {
    loc, _ := time.LoadLocation("America/Los_Angeles")
    current_time := time.Now().In(loc)
    return current_time.Format("Jan 2, 2006 at 3:04 PM")
}

func GetTimeStampFromDate(dtformat string) string {
    form := "Jan 2, 2006 at 3:04 PM"
    t2, _ := time.Parse(form, dtformat)
    return t2.Format("20060102150405")
}

Solution 4 - Go

According to the go documentation, Unix returns a local time.

> Unix returns the local Time corresponding to the given Unix time

This means the output would depend on the machine your code runs on, which, most often is what you need, but sometimes, you may want to have the value in UTC.

To do so, I adapted the snippet to make it return a time in UTC:

i, err := strconv.ParseInt("1405544146", 10, 64)
if err != nil {
	panic(err)
}
tm := time.Unix(i, 0)
fmt.Println(tm.UTC())

This prints on my machine (in CEST)

2014-07-16 20:55:46 +0000 UTC

Solution 5 - Go

I do a lot of logging where the timestamps are float64 and use this function to get the timestamps as string:

func dateFormat(layout string, d float64) string{
	intTime := int64(d)
	t := time.Unix(intTime, 0)
	if layout == "" {
		layout = "2006-01-02 15:04:05"
	}
	return t.Format(layout)
}

Solution 6 - Go

This is an old question but I noticed that a practical answer is missing.

For example, we are working with the MavLink protocol and we need to process a message with a structure defined here.

If we have this data structure:

Field Name Type Units Description
time_boot_ms uint64_t ms Timestamp (time since system boot).
press_abs float hPa Absolute pressure
press_diff float hPa Differential pressure 1
temperature int16_t cdegC Absolute pressure temperature
temperature_press_diff ** int16_t cdegC Differential pressure temperature (0, if not available). Report values of 0 (or 1) as 1 cdegC.

So, we receive constant updates that we need to process using the time_boot_ms as reference to insert them on the database and synchronize them with other messages.

What can we do?

As we noticed, the time is in milliseconds and everyone, that has some experience with Go, knows that for some unknown reason it's just way too complex to convert a millisecond resolution Unix timestamp to time.Time. The built-in time.Unix() function only supports second and nanosecond precision.

How we can get millisecond precision?

Well, we might wait until they release the version 1.7 of Go or we either have to multiply the milliseconds to nanoseconds or split them into seconds and nanoseconds.

Lets implement the second idea, spit the into seconds and nanoseconds:

unixUTCtime := time.Unix(ms/int64(1000), (ms%int64(1000))*int64(1000000))

Now we can encapsulate it in a func and use it in our main like this:

package main

import (
    "fmt"
    "time"
)

const msInSecond int64 = 1e3
const nsInMillisecond int64 = 1e6

// UnixToMS Converts Unix Epoch from milliseconds to time.Time
func UnixToMS (ms int64) time.Time {
    return time.Unix(ms/msInSecond, (ms%msInSecond)*nsInMillisecond)
}


func main() {
	unixTimes := [...]int64{758991688, 758992188, 758992690, 758993186}
	var unixUTCTimes []time.Time
	for index, unixTime := range unixTimes {
		unixUTCTimes = append(unixUTCTimes, UnixToMS(unixTime))
		if index > 0 {
			timeDifference := unixUTCTimes[index].Sub(unixUTCTimes[index-1])
			fmt.Println("Time difference in ms :--->", timeDifference)
		}
	}
}

The output will be:

Time difference in ms :---> 500ms
Time difference in ms :---> 502ms
Time difference in ms :---> 496ms

Check in Go Playground

Solution 7 - Go

for millis unix timestamp precision, in go1.18

    i, err := strconv.ParseInt("1652084489543", 10, 64)
    if err != nil {
        panic(err)
    }
    tm := time.UnixMilli(i)
    fmt.Println(tm)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionheyView Question on Stackoverflow
Solution 1 - GoANisusView Answer on Stackoverflow
Solution 2 - Gonegi YogiView Answer on Stackoverflow
Solution 3 - GoAdiView Answer on Stackoverflow
Solution 4 - GoThib-oView Answer on Stackoverflow
Solution 5 - GoSaxasmuView Answer on Stackoverflow
Solution 6 - GoTeocciView Answer on Stackoverflow
Solution 7 - GoJasonwView Answer on Stackoverflow