El manejo del tiempo es bastante complejo. Los supuestos incorrectos comunes sobre el tiempo incluyen lo siguiente.
- Un día consiste en 24 horas.
- Una hora contiene 60 minutos.
- Una semana consiste en siete días.
- Un año consta de 365 días.
Por ejemplo, 1 indica que agregar 24 horas a un momento específico en el tiempo no siempre resulta en un nuevo día del calendario.
Por lo tanto, al tratar con el tiempo, siempre use el paquete "time"
ya que ayuda a manejar estos supuestos incorrectos de manera más segura y precisa.
Uso de time.Time
para representar el tiempo instantáneo
Cuando se trata de tiempo instantáneo, use time.Time
y sus métodos para comparar, sumar o restar tiempo.
No recomendado:
func isActive(now, start, stop int) bool {
return start <= now && now < stop
}
Recomendado:
func isActive(now, start, stop time.Time) bool {
return (start.Before(now) || start.Equal(now)) && now.Before(stop)
}
Uso de time.Duration
para representar duraciones de tiempo
Cuando se trata de duraciones de tiempo, use time.Duration
.
No recomendado:
func poll(delay int) {
for {
// ...
time.Sleep(time.Duration(delay) * time.Millisecond)
}
}
poll(10) // ¿Está en segundos o milisegundos?
Recomendado:
func poll(delay time.Duration) {
for {
// ...
time.Sleep(delay)
}
}
poll(10*time.Second)
Volviendo al primer ejemplo, al agregar 24 horas a un tiempo instantáneo, el método utilizado depende de la intención. Si queremos el mismo punto en el tiempo en el próximo día del calendario (el día después del día actual), deberíamos usar Time.AddDate
. Sin embargo, si queremos asegurarnos de que un cierto momento sea 24 horas después que el anterior, deberíamos usar Time.Add
.
newDay := t.AddDate(0 /* años */, 0 /* meses */, 1 /* días */)
maybeNewDay := t.Add(24 * time.Hour)
Uso de time.Time
y time.Duration
con Sistemas Externos
Cuando sea posible, utilice time.Duration
y time.Time
en la interacción con sistemas externos, por ejemplo:
- Argumentos de línea de comandos:
flag
admitetime.Duration
a través detime.ParseDuration
. - JSON:
encoding/json
admite la codificación detime.Time
a una cadena RFC 3339 utilizando su métodoUnmarshalJSON
. - SQL:
database/sql
admite la conversión de columnasDATETIME
oTIMESTAMP
atime.Time
y devuelve si el controlador subyacente lo admite. - YAML:
gopkg.in/yaml.v2
admite el uso detime.Time
como una cadena RFC 3339 ytime.Duration
a través detime.ParseDuration
.
Cuando no se pueda usar time.Duration
en estas interacciones, utilice int
o float64
e incluya la unidad en el nombre del campo.
Por ejemplo, dado que encoding/json
no admite time.Duration
, se incluye la unidad en el nombre del campo.
No recomendado:
// {"interval": 2}
type Config struct {
Interval int `json:"interval"`
}
Recomendado:
// {"intervalMillis": 2000}
type Config struct {
IntervalMillis int `json:"intervalMillis"`
}
Cuando no se pueda usar time.Time
en estas interacciones, a menos que se acuerde lo contrario, utilice string
y formatee las marcas de tiempo según RFC 3339. Por defecto, Time.UnmarshalText
utiliza este formato y puede ser utilizado en Time.Format
y time.Parse
a través de time.RFC3339
.
Aunque no sea un problema práctico, tenga en cuenta que el paquete "time"
no admite el análisis de marcas de tiempo de segundos bisiestos (8728), y no tiene en cuenta los segundos bisiestos en los cálculos (15190). Al comparar dos momentos en el tiempo, la diferencia no incluirá ningún segundo bisiesto que pueda haber ocurrido entre esos dos momentos.