Go Unix Timestamp: time.Now, Unix(), UnixMilli & Locations
Go's time package is small and precise: a single time.Time type, an integer Unix accessor for every unit you need, and one Location pointer that decides how any instant prints. Here is the whole pattern.
time.Now() accessors: Unix() through UnixNano()
time.Now() is an instant, not a timestamp. Call an accessor to get the integer:
Unix() for seconds, UnixMilli() for milliseconds, and
UnixMicro()/UnixNano() beyond that — Go is the rare language with a
native accessor for every unit.
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
fmt.Println(now.Unix()) // seconds — 1767225600
fmt.Println(now.UnixMilli()) // milliseconds — 1767225600123
fmt.Println(now.UnixMicro()) // microseconds
fmt.Println(now.UnixNano()) // nanoseconds
}
From a timestamp to time.Time, in any location
time.Unix(sec, nsec) builds an instant in UTC (the zero Location).
time.UnixMilli(ms) and time.UnixMicro(us) exist too, so you never
hand-convert units. Display is a separate step: UTC(),
Local(), or In(loc) change only the view.
t := time.Unix(1767225600, 0) // UTC
fmt.Println(t) // 2026-01-01 00:00:00 +0000 UTC
fmt.Println(t.UTC()) // same instant, UTC
fmt.Println(t.Local()) // local zone
loc, _ := time.LoadLocation("Asia/Kolkata")
fmt.Println(t.In(loc)) // 2026-01-01 05:30:00 +0530 IST
fmt.Println(t.Format(time.RFC3339)) // 2026-01-01T00:00:00Z
Back to a timestamp: time.Date() and layout parsing
time.Date() takes an explicit location, and time.Parse requires a
layout string (Go's reference-time layout — "2006-01-02 15:04:05"). Parse with
time.UTC or a loaded location, never the zero value.
t := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)
t.Unix() // 1767225600
t.UnixMilli() // 1767225600000
parsed, err := time.Parse("2006-01-02 15:04:05", "2026-01-01 00:00:00")
// parsed is in UTC only because the layout has no zone — see pitfall below
parsed = parsed.In(time.UTC)
parsed.Unix()
Naive vs aware: Location is everything
Go's time.Time is always an absolute instant with a *time.Location
attached — there is no naive type. The naivety trap lives in parsing: a layout without
MST or -07:00 yields a time in UTC, not in local
time, and many newcomers assume otherwise. Use
time.ParseInLocation(layout, value, loc) when the input has no zone but you know
where it was recorded.
// Layout has no zone → result is UTC
t, _ := time.Parse("2006-01-02 15:04:05", "2026-01-01 00:00:00")
t.Location() // UTC
// Input recorded in IST without a zone — say so explicitly
loc, _ := time.LoadLocation("Asia/Kolkata")
t2, _ := time.ParseInLocation("2006-01-02 15:04:05", "2026-01-01 00:00:00", loc)
t2.Unix() // 1767220200 (not 1767225600)
Native precision in Go: nanoseconds on time.Time
Go's time.Time carries nanosecond precision, and the UnixNano()
accessor returns it directly. Storage layers often prefer seconds or milliseconds — pick the
accessor that matches the column, and don't divide nanoseconds with floating point
(int64 division is exact).
Go pitfalls: reference-time layouts and Parse's default UTC
- time.Parse defaults to UTC for zone-less layouts — use
ParseInLocationfor local input. - Formatting — Go uses reference-time layouts, not format codes;
"2006-01-02"is the date. - Comparing times —
==compares instants correctly, but JSON round-trips lose monotonic parts; strip them witht.Round(0). - 2038 — irrelevant in Go: int64 seconds last for billions of years.
Cross-check the Go output in the live converter
Cross-check any value in the main epoch converter, or copy the current timestamp from the Go snippet tab on the homepage.
First published · Last reviewed · Maintained and developed by the Real Epoch Converter team · Email · Contact · Methodology
Sources & references
the same task in every language
JavaScript · Python · PHP · SQL · Go · Java · C# · Rust · C++ · PowerShell
the browser-based epoch time converter is a quick second opinion on a time.Time you are debugging.