O tratamento do tempo é bastante complexo. Suposições incorretas comuns sobre o tempo incluem o seguinte.
- Um dia consiste em 24 horas.
- Uma hora contém 60 minutos.
- Uma semana consiste em sete dias.
- Um ano compreende 365 dias.
Por exemplo, 1 indica que adicionar 24 horas a um ponto específico no tempo nem sempre resulta em um novo dia no calendário.
Portanto, ao lidar com o tempo, sempre use o pacote "time" pois ele ajuda a lidar com essas suposições incorretas de forma mais segura e precisa.
Utilizando time.Time para Representar o Tempo Instantâneo
Ao lidar com o tempo instantâneo, utilize time.Time e seus métodos para comparar, adicionar ou subtrair tempo.
Não 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)
}
Utilizando time.Duration para Representar Durações de Tempo
Ao lidar com durações de tempo, utilize time.Duration.
Não recomendado:
func poll(delay int) {
for {
// ...
time.Sleep(time.Duration(delay) * time.Millisecond)
}
}
poll(10) // Está em segundos ou milissegundos?
Recomendado:
func poll(delay time.Duration) {
for {
// ...
time.Sleep(delay)
}
}
poll(10*time.Second)
Voltando ao primeiro exemplo, ao adicionar 24 horas a um tempo instantâneo, o método utilizado depende da intenção. Se quisermos o mesmo ponto no tempo no próximo dia do calendário (o dia após o dia atual), devemos usar Time.AddDate. No entanto, se queremos garantir que um certo momento seja 24 horas após o anterior, devemos usar Time.Add.
novoDia := t.AddDate(0 /* anos */, 0 /* meses */, 1 /* dias */)
talvezNovoDia := t.Add(24 * time.Hour)
Usando time.Time e time.Duration com Sistemas Externos
Sempre que possível, use time.Duration e time.Time na interação com sistemas externos, por exemplo:
- Flags de linha de comando:
flagsuportatime.Durationatravés detime.ParseDuration. - JSON:
encoding/jsonsuporta a codificação detime.Timepara uma string RFC 3339 usando seu métodoUnmarshalJSON. - SQL:
database/sqlsuporta a conversão de colunasDATETIMEouTIMESTAMPparatime.Timee retorna se o driver subjacente suporta isso. - YAML:
gopkg.in/yaml.v2suporta o uso detime.Timecomo uma string RFC 3339 etime.Durationatravés detime.ParseDuration.
Quando time.Duration não puder ser usado nessas interações, use int ou float64 e inclua a unidade no nome do campo.
Por exemplo, uma vez que encoding/json não suporta time.Duration, a unidade é incluída no nome do campo.
Não recomendado:
// {"interval": 2}
type Config struct {
Interval int `json:"interval"`
}
Recomendado:
// {"intervalMillis": 2000}
type Config struct {
IntervalMillis int `json:"intervalMillis"`
}
Quando time.Time não puder ser usado nessas interações, a menos que acordado de outra forma, use string e formate os carimbos de tempo de acordo com RFC 3339. Por padrão, Time.UnmarshalText usa este formato e pode ser usado em Time.Format e time.Parse através de time.RFC3339.
Embora não seja um problema prático, observe que o pacote "time" não suporta a análise de carimbos de tempo de segundo bissexto (8728), e não leva em consideração os segundos bissextos em cálculos (15190). Se comparar dois momentos no tempo, a diferença não incluirá nenhum segundo bissexto que possa ter ocorrido entre esses dois momentos.