Skip to content

time

The time package provides two central types:

  • time.Time — an instant in time with nanosecond precision, always carrying a location (timezone).
  • time.Duration — a signed 64-bit integer representing a length of time in nanoseconds. Duration constants like time.Hour, time.Minute, time.Second, and time.Millisecond make arithmetic readable.
d := 2*time.Hour + 30*time.Minute + 15*time.Second
fmt.Println(d) // 2h30m15s

In production code you call time.Now() to get the current instant. For tests and deterministic examples, use time.Date:

t := time.Date(2024, 1, 2, 15, 4, 5, 0, time.UTC)
// year, month, day, hour, min, sec, nanosec, location

time.Month values (time.January through time.December) are typed constants; you can also pass integer literals (1–12) because they are assignable to time.Month.

Go uses a concrete reference time instead of abstract format codes like YYYY-MM-DD. The reference moment is:

Mon Jan 2 15:04:05 MST 2006

To format a time, write out the reference moment in the shape you want:

t.Format("2006-01-02") // "2024-01-02"
t.Format("15:04:05") // "15:04:05"
t.Format("02 Jan 2006 15:04 MST") // "02 Jan 2024 15:04 UTC"
t.Format(time.RFC3339) // "2024-01-02T15:04:05Z"

time.Parse is the inverse of Format — it takes a layout and a string:

parsed, err := time.Parse("2006-01-02", "2024-06-15")
// parsed is midnight UTC on June 15, 2024

The layout string must match the reference time components you used — the same characters in the same positions.

deadline := t.Add(72 * time.Hour) // 3 days later
diff := deadline.Sub(t) // time.Duration: 72h0m0s
before := deadline.Before(t) // false
after := deadline.After(t) // true

Add takes a Duration and returns a Time. Sub takes two Time values and returns the Duration between them.

package main
import (
"fmt"
"time"
)
func main() {
// Fixed time — deterministic in any interpreter
t := time.Date(2024, 1, 2, 15, 4, 5, 0, time.UTC)
fmt.Println(t)
// Formatting with the reference layout
fmt.Println(t.Format("2006-01-02"))
fmt.Println(t.Format("15:04:05"))
fmt.Println(t.Format("Mon, 02 Jan 2006 15:04:05 MST"))
fmt.Println(t.Format(time.RFC3339))
// Parsing
parsed, err := time.Parse("2006-01-02", "2024-06-15")
if err == nil {
fmt.Println(parsed.Format("January 2, 2006"))
}
// Arithmetic
deadline := t.Add(72 * time.Hour)
fmt.Println(deadline.Format("2006-01-02 15:04:05"))
diff := deadline.Sub(t)
fmt.Println(diff)
// Duration construction
d := 2*time.Hour + 30*time.Minute
fmt.Println(d)
// Accessing date parts
fmt.Println(t.Year(), t.Month(), t.Day())
fmt.Println(t.Hour(), t.Minute(), t.Second())
}
What is Go's reference time used for formatting?
Which call returns a new time.Time exactly 24 hours after t?
What does t.Sub(other) return?
Why should you avoid time.Now() in playground / test snippets?