Convert Unix Timestamp in Go — Using the time Package
Table of Contents
Go's time package handles Unix timestamps with three main functions: time.Unix, time.UnixMilli, and time.UnixMicro. Each takes a timestamp and returns a time.Time value. Going the other way, every time.Time has .Unix(), .UnixMilli(), and .UnixNano() methods.
The thing that trips up Go newcomers is the format string — Go uses a specific reference time instead of strftime characters. We will cover that too.
Convert Unix Timestamp to time.Time
The time.Unix(sec, nsec int64) function takes seconds and nanoseconds. For a standard Unix timestamp, pass 0 for nanoseconds.
package main
import (
"fmt"
"time"
)
func main() {
// From seconds
ts := int64(1711000000)
t := time.Unix(ts, 0)
fmt.Println(t.UTC()) // 2024-03-21 07:46:40 +0000 UTC
// From milliseconds (Go 1.17+)
tsMs := int64(1711000000123)
t2 := time.UnixMilli(tsMs)
// From microseconds (Go 1.17+)
tsMicro := int64(1711000000123456)
t3 := time.UnixMicro(tsMicro)
// From nanoseconds — use time.Unix with the nsec arg
tsNano := int64(1711000000123456789)
t4 := time.Unix(0, tsNano)
}
The default time zone for the result is whatever the program was started with — usually the system local time. Always call .UTC() immediately if you want UTC, or .In(location) for a specific zone.
Convert time.Time Back to Unix Timestamp
// Current Unix timestamp (seconds)
ts := time.Now().Unix()
// Current time in milliseconds
tsMs := time.Now().UnixMilli()
// Current time in nanoseconds — Go's native unit
tsNano := time.Now().UnixNano()
// From a parsed time
parsed, _ := time.Parse(time.RFC3339, "2024-03-21T07:46:40Z")
ts2 := parsed.Unix()
Go internally stores time as nanoseconds since the year 1 (not the Unix epoch). The .Unix() family of methods does the conversion to epoch-relative values when you ask for them. Performance is identical for all three precision levels.
Go's Reference Time Format
Go does not use strftime characters. Instead it uses a specific reference time: Mon Jan 2 15:04:05 MST 2006. You write your format by laying out how that exact reference time should look in your desired format.
// Reference time: Mon Jan 2 15:04:05 MST 2006
// What you write: "2006-01-02 15:04:05" → ISO-style
// What you write: "Jan 2, 2006" → "Mar 21, 2024"
// What you write: "01/02/2006" → "03/21/2024"
t := time.Unix(1711000000, 0).UTC()
fmt.Println(t.Format("2006-01-02 15:04:05"))
// 2024-03-21 07:46:40
fmt.Println(t.Format("Mon, 02 Jan 2006 15:04:05 GMT"))
// Thu, 21 Mar 2024 07:46:40 GMT
// Or use one of the predefined constants
fmt.Println(t.Format(time.RFC3339))
// 2024-03-21T07:46:40Z
The numbers are mnemonic: 1=month, 2=day, 3=hour (12), 4=minute, 5=second, 6=year, 7=tz. They go in increasing order. It feels weird at first but you stop noticing after a few weeks.
Predefined constants in the time package: time.RFC3339, time.RFC1123, time.Kitchen, time.Stamp. Use these instead of writing format strings when you can.
Parsing Date Strings and Handling Timezones
// Parse with the same reference time format
t, err := time.Parse("2006-01-02 15:04:05", "2024-03-21 07:46:40")
if err != nil {
panic(err)
}
ts := t.Unix() // 1711006000 (assumed UTC because no zone in input)
// Parse in a specific timezone
loc, _ := time.LoadLocation("America/New_York")
t2, _ := time.ParseInLocation("2006-01-02 15:04:05", "2024-03-21 07:46:40", loc)
// Convert between zones
nyTime := time.Unix(1711000000, 0).In(loc)
tokyoLoc, _ := time.LoadLocation("Asia/Tokyo")
tokyoTime := nyTime.In(tokyoLoc)
Two things to remember on Go time: time.Parse assumes UTC if the input has no zone, and time.LoadLocation reads from the system timezone database which may not be present in minimal Docker images. If you ship Go in distroless or scratch containers, embed the tz database with import _ "time/tzdata".
For a quick value check without compiling Go, the free Unix timestamp converter handles seconds and milliseconds.
Try It Free — No Signup Required
Runs 100% in your browser. No data is collected, stored, or sent anywhere.
Open Free Unix Timestamp ConverterFrequently Asked Questions
How do I convert a Unix timestamp to time.Time in Go?
Use time.Unix(seconds, 0) for seconds-based timestamps, time.UnixMilli(ms) for milliseconds, or time.UnixMicro(us) for microseconds. All three return a time.Time value in the local timezone — call .UTC() to normalize.
How do I get the current Unix timestamp in Go?
time.Now().Unix() returns the current Unix timestamp in seconds. UnixMilli() and UnixNano() give milliseconds and nanoseconds. All three are based on the system clock at the moment of the call.
Why does Go use 2006-01-02 instead of YYYY-MM-DD for date formats?
Go uses a specific reference time (Mon Jan 2 15:04:05 MST 2006) and you describe your format by writing how that reference time should look. The numbers are mnemonic: 1, 2, 3, 4, 5, 6, 7 = month, day, hour, minute, second, year, timezone. It feels weird but is actually consistent.
How do I parse a date string with timezone in Go?
Use time.ParseInLocation with a *time.Location loaded from time.LoadLocation("America/New_York"). The standard time.Parse assumes UTC if the input has no explicit zone, which usually causes bugs.
Why does my Go time.LoadLocation fail in Docker?
Minimal Docker images (alpine, scratch, distroless) often do not include the system timezone database. Embed it in your binary by importing _ "time/tzdata" — this adds about 800KB but makes timezone loading work in any container.
What is the difference between Unix() and UnixNano() in Go?
Unix() returns seconds since the epoch as int64. UnixNano() returns nanoseconds. Go internally stores time at nanosecond precision, so UnixNano() is the most precise. Use the one that matches what your downstream consumer expects.

