Vai al contenuto
eLearner.app
Modulo 8 · Lezione 4 di 539/50 nel corso~12 min
Lezioni del modulo (4/5)

Il pacchetto `time`

Il pacchetto time modella tre concetti distinti: istanti (time.Time), durate (time.Duration) e strumenti periodici (timer, ticker). Distinguerli è cruciale: un istante è un punto sulla linea temporale, una durata è un intervallo.

time.Time — istanti

Go
now := time.Now()                // istante corrente nel fuso locale
utc := now.UTC()                 // stesso istante in UTC
later := now.Add(2 * time.Hour)  // somma una durata
diff := later.Sub(now)           // 2h0m0s (è una Duration)

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

time.Time è immutabile: tutti i metodi Add, Truncate, Round ritornano una nuova Time.

Per confrontare istanti usa Before, After, Equal. Non usare == se gli istanti possono avere fuso/monotonic clock diversi.

time.Duration — intervalli

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

const timeout = 5 * time.Second

time.Duration è un alias di int64 che conta nanosecondi. Le costanti time.Nanosecond, time.Microsecond, time.Millisecond, time.Second, time.Minute, time.Hour sono di tipo Duration.

Parsing e formatting: il layout di riferimento

Go non usa stringhe stile YYYY-MM-DD. Usa un istante di riferimento canonico:

Code
Mon Jan 2 15:04:05 MST 2006

cioè 01/02 03:04:05PM '06 -0700. Memorizzando questo layout (mnemonic: 1-2-3-4-5-6-7) puoi formattare qualsiasi data:

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")

La stdlib offre layout pronti: time.RFC3339 ("2006-01-02T15:04:05Z07:00"), time.RFC1123, time.Kitchen ("3:04PM").

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

Misurare il tempo

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

time.Since usa il monotonic clock: non viene perturbato da aggiustamenti dell'orologio di sistema (NTP, daylight saving). Per misurazioni di performance è quello che vuoi.

Timer e Ticker

  • time.After(d) ritorna un chan time.Time che riceve una sola volta dopo d. Utile in select:
Go
select {
case res := <-ch:
    fmt.Println("ok", res)
case <-time.After(2 * time.Second):
    return errors.New("timeout")
}
  • time.NewTimer(d) è una variante stoppabile (t.Stop()).
  • time.NewTicker(d) invia ripetutamente ogni d. Ricordati defer ticker.Stop() per evitare goroutine leak.
Go
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for range ticker.C {
    fmt.Println("tick")
}

Esercizi

Esercizio#go.m8.l4.e1
Tentativi: 0Caricamento…

Stampa l'istante corrente formattato secondo time.RFC3339.

Caricamento editor…

Soluzione disponibile dopo 3 tentativi

Esercizio#go.m8.l4.e2
Tentativi: 0Caricamento…

Misura quanto dura una time.Sleep di 10ms usando time.Since e stampa il risultato.

Caricamento editor…

Soluzione disponibile dopo 3 tentativi

Quiz#go.m8.l4.e3
Pronto

Di quale tipo è la costante `time.Second`?

Go
d := time.Second
// d ha tipo ???
Opzioni di risposta