Standard library patterns · 3 MIN READ

A Duration is a number of nanoseconds with a type

Write a timeout without wondering what unit it is in.

time.Duration is an int64 counting nanoseconds, and the constants are what make it readable: 5 * time.Second is a multiplication, not a function call. That is also the trap — a bare 5 is five nanoseconds, and time.Sleep(5) requests five nanoseconds, not five seconds. Scheduler timing may make the actual wait longer.

Two more worth knowing on sight: end.Sub(start) gives a Duration, and comparing Times uses Before, After and Equal rather than the operators, because a Time carries a monotonic reading as well as a wall clock.

SEE THE IDEA

Make units visible in every duration

  1. 01

    Quantity

    go
    5

    A plain number has no readable unit

  2. 02

    Unit

    go
    time.Second

    A typed duration constant

  3. 03

    Timeout

    go
    5 * time.Second

    An explicit interval

A Duration is an int64 measured in nanoseconds.

In practice

Use Add and Sub for instants and Before, After or Equal for comparisons. Time values may contain location and monotonic information, so == can differ from Equal. A context timeout or timer is often more useful than Sleep when the operation must be cancelable.

Watch out

time.Sleep(5) requests five nanoseconds; scheduling overhead determines when execution actually resumes.

Official reference ↗

Read and predict

go
package main

import (
	"fmt"
	"time"
)

func main() {
	d := 90 * time.Second
	fmt.Println(d)
	fmt.Println(d.Minutes())

	start := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
	end := start.Add(36 * time.Hour)
	fmt.Println(end.Sub(start))
	fmt.Println(end.After(start))
}

What does this print? Durations print themselves.

Try it yourself

Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.

Progress stays in this browser. No account needed.