time.Since în Go

Since: cât timp a trecut de la t până acum; Until: cât timp mai este până la t. Ambele returnează time.Duration.

Sintaxă
func Since(t Time) Duration
func Until(t Time) Duration   // Go 1.8

Ce face time.Since

time.Since(start) este scurtătura pentru time.Now().Sub(start): durata scursă de la start. Este modul obișnuit de a măsura cât durează o operație: notezi start := time.Now(), faci operația, apoi afișezi time.Since(start). Dacă start vine tot de la Now, se folosește ceasul monoton și rezultatul nu este afectat de schimbarea orei sistemului.

time.Until(t) este inversul: t.Sub(time.Now()), adică cât mai rămâne până la t; devine negativ după ce t a trecut. E util pentru „expiră în …” sau ca să afli cât timp mai are un context până la termen.

Rezultatul are multe zecimale (1.204391875s). Pentru afișare îl rotunjești cu Round sau Truncate.

Parametri

Parametru Descriere
t Momentul de referință.

Ce returnează

O durată (time.Duration).

Exemple

Exemplul 1: Durata unei operații

Măsurarea exactă diferă de la o rulare la alta, deci o rotunjim în jos la 100 ms: o pauză de 210 ms dă 200 ms.

package main

import (
	"fmt"
	"time"
)

func genereazaRaport() {
	time.Sleep(210 * time.Millisecond) // simulăm o operație lentă
}

func main() {
	start := time.Now()
	genereazaRaport()
	durata := time.Since(start)
	fmt.Println("Cel puțin 210ms:", durata >= 210*time.Millisecond)
	fmt.Println("Rotunjit în jos:", durata.Truncate(100*time.Millisecond))
}

Rezultat

Cel puțin 210ms: true
Rotunjit în jos: 200ms

Exemplul 2: Cât mai e până la un termen

package main

import (
	"fmt"
	"time"
)

func main() {
	expira := time.Now().Add(2*time.Hour + 30*time.Minute)
	ramas := time.Until(expira)
	fmt.Println("Oferta expiră în:", ramas.Round(time.Minute))

	trecut := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
	fmt.Println("Termenul din 2020 a trecut:", time.Until(trecut) < 0)
	fmt.Println("Au trecut peste 6 ani:", time.Since(trecut) > 6*365*24*time.Hour)
}

Rezultat

Oferta expiră în: 2h30m0s
Termenul din 2020 a trecut: true
Au trecut peste 6 ani: true

Exemplul 3: Măsurare afișată direct

Valoarea exactă diferă la fiecare rulare.

package main

import (
	"fmt"
	"strings"
	"time"
)

func main() {
	start := time.Now()
	text := strings.Repeat("Go ", 1_000_000)
	cuvinte := len(strings.Fields(text))
	fmt.Println("Cuvinte:", cuvinte, "în", time.Since(start))
}

Rezultat posibil (diferă la fiecare rulare)

Cuvinte: 1000000 în 18.402166ms

Greșeli frecvente

  • Măsori cu time.Since o operație foarte scurtă o singură dată și tragi concluzii: rezultatul variază mult. Pentru măsurători de performanță folosește benchmark-urile din testing.
  • Folosești time.Since(t) cu un t citit din baza de date sau dintr-un fișier: nu are ceas monoton, deci o schimbare a orei sistemului afectează rezultatul. Pentru durate scurte în program, păstrează momentul de la Now.

Comenzi înrudite

  • time.Now: Returnează momentul curent, în fusul orar local, cu o citire a ceasului monoton pentru măsurarea duratelor.
  • time.Time.Sub: Calculează cât timp a trecut între două momente și returnează diferența ca time.Duration.
  • time.Duration.Round: Rotunjește o durată la un multiplu: Round la cel mai apropiat, Truncate în jos (ex. la secundă pentru afișare).
  • context.WithDeadline: Creează un context care se anulează singur la un moment fix (ora limită), nu după o durată.