La manipulation du temps est assez complexe. Les fausses hypothèses courantes sur le temps incluent les suivantes.
- Une journée se compose de 24 heures.
- Une heure contient 60 minutes.
- Une semaine se compose de sept jours.
- Une année comprend 365 jours.
Par exemple, 1 indique qu'ajouter 24 heures à un moment spécifique ne résulte pas toujours en un nouveau jour calendaire.
Par conséquent, lors de la manipulation du temps, utilisez toujours le package "time"
car il permet de gérer ces fausses hypothèses de manière plus sûre et précise.
Utilisation de time.Time
pour représenter le temps instantané
Lors de la manipulation du temps instantané, utilisez time.Time
et ses méthodes pour comparer, ajouter ou soustraire du temps.
Non recommandé:
func isActive(now, start, stop int) bool {
return start <= now && now < stop
}
Recommandé:
func isActive(now, start, stop time.Time) bool {
return (start.Before(now) || start.Equal(now)) && now.Before(stop)
}
Utilisation de time.Duration
pour représenter les durées
Lors de la manipulation des durées, utilisez time.Duration
.
Non recommandé:
func poll(delay int) {
for {
// ...
time.Sleep(time.Duration(delay) * time.Millisecond)
}
}
poll(10) // Est-ce en secondes ou en millisecondes ?
Recommandé:
func poll(delay time.Duration) {
for {
// ...
time.Sleep(delay)
}
}
poll(10*time.Second)
En revenant à premier exemple, lors de l'ajout de 24 heures à un instant précis, la méthode utilisée dépend de l'intention. Si nous voulons le même point dans le temps le lendemain (le jour suivant le jour actuel), nous devrions utiliser Time.AddDate
. Cependant, si nous voulons nous assurer qu'un certain moment est 24 heures plus tard que le précédent, nous devrions utiliser Time.Add
.
nouveauJour := t.AddDate(0 /* années */, 0 /* mois */, 1 /* jours */)
peutÊtreNouveauJour := t.Add(24 * time.Hour)
Utilisation de time.Time
et time.Duration
avec des systèmes externes
Chaque fois que possible, utilisez time.Duration
et time.Time
dans l'interaction avec des systèmes externes, par exemple :
- Arguments de ligne de commande :
flag
prend en chargetime.Duration
viatime.ParseDuration
. - JSON :
encoding/json
prend en charge l'encodage detime.Time
en une chaîne RFC 3339 en utilisant sa méthodeUnmarshalJSON
. - SQL :
database/sql
prend en charge la conversion des colonnesDATETIME
ouTIMESTAMP
entime.Time
, et renvoie si le pilote sous-jacent le prend en charge. - YAML :
gopkg.in/yaml.v2
prend en charge l'utilisation detime.Time
comme chaîne RFC 3339 ettime.Duration
viatime.ParseDuration
.
Lorsque time.Duration
ne peut être utilisé dans ces interactions, utilisez int
ou float64
et incluez l'unité dans le nom du champ.
Par exemple, puisque encoding/json
ne prend pas en charge time.Duration
, l'unité est incluse dans le nom du champ.
Non recommandé :
// {"interval": 2}
type Config struct {
Interval int `json:"interval"`
}
Recommandé :
// {"intervalMillis": 2000}
type Config struct {
IntervalMillis int `json:"intervalMillis"`
}
Lorsque time.Time
ne peut être utilisé dans ces interactions, sauf accord contraire, utilisez string
et formatez les horodatages conformément à RFC 3339. Par défaut, Time.UnmarshalText
utilise ce format et peut être utilisé dans Time.Format
et time.Parse
via time.RFC3339
.
Bien que ce ne soit pas un problème pratique, veuillez noter que le package "time"
ne prend pas en charge l'analyse des horodatages de seconde intercalaire (8728), et ne prend pas en compte les secondes intercalaires dans les calculs (15190). Si vous comparez deux moments dans le temps, la différence ne tiendra pas compte d'éventuelles secondes intercalaires qui auraient pu se produire entre ces deux moments.