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:
flag
suportatime.Duration
através detime.ParseDuration
. - JSON:
encoding/json
suporta a codificação detime.Time
para uma string RFC 3339 usando seu métodoUnmarshalJSON
. - SQL:
database/sql
suporta a conversão de colunasDATETIME
ouTIMESTAMP
paratime.Time
e retorna se o driver subjacente suporta isso. - YAML:
gopkg.in/yaml.v2
suporta o uso detime.Time
como uma string RFC 3339 etime.Duration
atravé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.