Skip to main content
eLearner.app
Module 8 · Lesson 4 of 539/50 in the course~12 min
Module lessons (4/5)

The `time` package

The time package models three distinct concepts: instants (time.Time), durations (time.Duration) and periodic tools (timer, ticker). Distinguishing them is crucial: an instant is a point on the timeline, a duration is an interval.

time.Time — instants

Go
now := time.Now()                // current instant in the local timezone
utc := now.UTC()                 // same instant in UTC
later := now.Add(2 * time.Hour)  // add a duration
diff := later.Sub(now)           // 2h0m0s (it's a Duration)

fmt.Println(now.Year(), now.Month(), now.Day())
fmt.Println(now.Weekday())

time.Time is immutable: all methods Add, Truncate, Round return a new Time.

To compare instants use Before, After, Equal. Do not use == if the instants can have different timezones/monotonic clocks.

time.Duration — intervals

Go
d := 250 * time.Millisecond
fmt.Println(d)         // 250ms
fmt.Println(d.Seconds()) // 0.25 (float64)

const timeout = 5 * time.Second

time.Duration is an alias of int64 that counts nanoseconds. The constants time.Nanosecond, time.Microsecond, time.Millisecond, time.Second, time.Minute, time.Hour are of type Duration.

Parsing and formatting: the reference layout

Go does not use strings like YYYY-MM-DD. It uses a canonical reference instant:

Code
Mon Jan 2 15:04:05 MST 2006

i.e. 01/02 03:04:05PM '06 -0700. By memorizing this layout (mnemonic: 1-2-3-4-5-6-7) you can format any date:

Go
const layout = "2006-01-02 15:04:05"
s := time.Now().Format(layout)            // "2026-05-16 14:30:00"
t, err := time.Parse(layout, "2026-05-16 14:30:00")

The stdlib offers ready-made layouts: time.RFC3339 ("2006-01-02T15:04:05Z07:00"), time.RFC1123, time.Kitchen ("3:04PM").

Go
fmt.Println(time.Now().Format(time.RFC3339))

Measuring time

Go
start := time.Now()
work()
elapsed := time.Since(start)  // = time.Now().Sub(start)
fmt.Println("ci ha messo", elapsed)

time.Since uses the monotonic clock: it is not perturbed by system clock adjustments (NTP, daylight saving). For performance measurements that is what you want.

Timer and Ticker

  • time.After(d) returns a chan time.Time that receives only once after d. Useful in select:
Go
select {
case res := <-ch:
    fmt.Println("ok", res)
case <-time.After(2 * time.Second):
    return errors.New("timeout")
}
  • time.NewTimer(d) is a stoppable variant (t.Stop()).
  • time.NewTicker(d) sends repeatedly every d. Remember defer ticker.Stop() to avoid goroutine leaks.
Go
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for range ticker.C {
    fmt.Println("tick")
}

Exercises

Exercise#go.m8.l4.e1
Attempts: 0Loading…

Print the current instant formatted according to time.RFC3339.

Loading editor…

Solution available after 3 attempts

Exercise#go.m8.l4.e2
Attempts: 0Loading…

Measure how long a time.Sleep of 10ms takes using time.Since and print the result.

Loading editor…

Solution available after 3 attempts

Quiz#go.m8.l4.e3
Ready

What type is the constant `time.Second`?

Go
d := time.Second
// d ha tipo ???
Answer options