Integración de time, zonas horarias y context
El paquete time de Go modela instantes, duraciones y eventos recurrentes.
Busca en todas las páginas de la documentación
El paquete time de Go modela instantes, duraciones y eventos recurrentes.
context adjunta plazos y cancelación a esas operaciones para que los servidores detengan el trabajo cuando los clientes se desconectan o los presupuestos expiran.
Usa time.Time para instantes de calendario y time.Duration para intervalos transcurridos.
Las lecturas del reloj monotónico evitan que los saltos del horario de verano corrompan las mediciones de Since.
Carga ubicaciones con time.LoadLocation para una visualización local correcta; almacena UTC en bases de datos.
Empareja context.WithTimeout con llamadas bloqueantes para que las goroutines salgan puntualmente.
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
timer := time.NewTimer(500 * time.Millisecond)
defer timer.Stop()
select {
case <-timer.C:
// trabajo
case <-ctx.Done():
return ctx.Err()
}Cuándo usar esto:
time.Since y time.Until.time.Ticker.context.Context.package main
import (
"context"
"fmt"
"time"
)
func fetchWithDeadline(ctx context.Context, url string) error {
ctx, cancel := context.WithTimeout(ctx, 800*time.Millisecond)
defer cancel()
done := make(chan error, 1)
go func() {
// marcador de posición para llamada net/http o de base de datos
time.Sleep(300 * time.Millisecond)
done <- nil
}()
select {
case err := <-done:
return err
case <-ctx.Done():
return fmt.Errorf("fetch %s: %w", url, ctx.Err())
}
}
func nextBusinessOpen(now time.Time, loc *time.Location) time.Time {
local := now.In(loc)
// ejemplo ingenuo: próximo 09:00 local en un día laborable
open := time.Date(local.Year(), local.Month(), local.Day(), 9, 0, 0, 0, loc)
if !local.Before(open) {
open = open.Add(24 * time.Hour)
}
return open.UTC()
}
func main() {
loc, err := time.LoadLocation("America/New_York")
if err != nil {
panic(err)
}
if err := fetchWithDeadline(context.Background(), "https://example.com"); err != nil {
panic(err)
}
utcNow := time.Now().UTC()
fmt.Println("próxima apertura UTC:", nextBusinessOpen(utcNow, loc))
}Lo que esto demuestra:
select uniendo trabajo bloqueante y cancelación.LoadLocation para nombres de zona IANA y conversión de instantes de visualización a UTC.time.Now captura lecturas del reloj y del tiempo transcurrido en un solo valor time.Time.t2.Sub(t1)) utiliza lecturas del tiempo transcurrido cuando ambos tiempos comparten la misma base monotónica.time.Timer se dispara una vez; time.Ticker se repite hasta Stop.context.WithDeadline y WithTimeout programan la cancelación automática en un instante derivado de time.Time.| Tipo | Usar para | Evitar para |
|---|---|---|
time.Time | Instantes, serialización con RFC3339 | Almacenar segundos Unix sin información de zona |
time.Duration | Tiempos de espera, backoff, métricas | Aritmética de calendario (usar AddDate) |
time.Location | Visualización regional | time.FixedZone fijos para regiones con horario de verano |
time.Ticker | Envío periódico de métricas | Retrasos de un solo disparo (usar Timer) |
// Analiza y formatea con diseños explícitos (tiempo de referencia Lun 2 Ene 15:04:05 MST 2006):
t, _ := time.Parse(time.RFC3339, "2026-07-15T12:00:00Z")
// Sleep no es cancelable - prefiere select:
select {
case <-time.After(delay):
case <-ctx.Done():
return ctx.Err()
}time.Sleep sin context - El apagado y la cancelación del cliente no pueden interrumpir el sleep. Solución: select en ctx.Done() y time.After.Location.timer.Stop() o ticker.Stop() - Fuga goroutines hasta la hora de disparo. Solución: diferir Stop() inmediatamente después de la creación.time.Time con == entre zonas - El mismo instante puede diferir en los campos de visualización. Solución: comparar t1.Equal(t2) o convertir ambos a UTC.time.After en bucles ajustados - Crea un nuevo temporizador por iteración. Solución: reutilizar time.NewTimer y restablecer cuidadosamente.context.Background() en servidores - Ignora la cancelación de la solicitud entrante. Solución: aceptar ctx de r.Context() o del ámbito padre.| Alternativa | Usar cuándo | No usar cuándo |
|---|---|---|
time.Tick | Solo demostraciones rápidas | Código de producción (no se puede detener el ticker subyacente) |
Bibliotecas cron | Horarios complejos | Intervalos fijos simples son suficientes |
Milisegundos Unix int64 | Formato de cable multiplataforma | Operaciones de duración en memoria sin conversión |
Falsificaciones de prueba clock | Pruebas deterministas | Programación de producción |
Una lectura oculta dentro de time.Time utilizada para mediciones de duración.
Ignora los ajustes del reloj de pared como los saltos de NTP al calcular Since y Until.
Almacena instantes UTC en bases de datos, a menudo como TIMESTAMPTZ o cadenas RFC3339.
Usa time.Time en código Go para semántica de zona y monotónica.
time.LoadLocation("Europe/Berlin") usando nombres IANA de la base de datos zoneinfo incluida con Go.
Evita codificar valores fijos de offset UTC+1 para regiones con horario de verano.
Un Timer envía un valor en C después de un retraso.
Un Ticker envía repetidamente hasta Stop.
Usa tickers para bucles de latidos, temporizadores para retrasos de un solo disparo.
cancel libera los recursos del temporizador asociado anticipadamente si el trabajo finaliza antes del plazo.
Es requerido incluso cuando el tiempo de espera se dispara.
Los tiempos de espera de lectura/escritura de http.Server cancelan r.Context() cuando se activan.
Los manejadores deben pasar r.Context() a downstream para que las llamadas a la base de datos también se detengan.
ParseDuration admite desde ns hasta horas (h).
Para días o meses, usa time.AddDate en time.Time, no cadenas de duración.
El plazo del context expiró antes de que el trabajo se completara.
Distingue de context.Canceled cuando algo llamó explícitamente a cancel().
time.Now devuelve la hora local del sistema con la ubicación establecida en Local.
Llama a .UTC() antes de persistir o comparar entre máquinas.
Inyecta una pequeña interfaz que envuelva Now y After, o pasa plazos como parámetros.
Evita dormir tiempo real en pruebas unitarias.
time.Tick no se puede detener, lo que provoca una fuga de una goroutine durante la vida útil del proceso.
Usa time.NewTicker y Stop en su lugar.
Un select con default puede girar ocupado si consultás ticker.C sin bloquear.
Estructura los bucles para que bloqueen en ticker.C o combínalos con ctx.Done().
time.SinceVersiones de Stack: Esta página fue escrita para Go 1.26.x (predeterminado Green Tea GC, go fix modernizers - verificar parche en la compilación), chi (última versión - verificar en la compilación), gin (última versión - verificar en la compilación), echo (última versión - verificar en la compilación), google.golang.org/grpc (última versión - verificar en la compilación), sigs.k8s.io/controller-runtime (última versión - verificar en la compilación), kubebuilder (última versión - verificar en la compilación), tinygo (última versión - verificar objetivos de placa en la compilación), wazero (última versión - verificar en la compilación) y golangci-lint (última versión - verificar conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 16 jul 2026