L'essentiel en un programme
time.Now() renvoie l'heure locale actuelle, time.Sleep met en pause la goroutine courante, time.Since mesure le temps écoulé, et time.Date construit un instant précis. La suite de cette page reprend chaque élément un par un. Les exemples utilisent des dates fixes et l'UTC pour que leur sortie soit la même où que vous les exécutiez.
Sleep et Duration
Un time.Duration est un int64 qui compte des nanosecondes. Le package définit des constantes pour construire des valeurs lisibles :
| Constante | Valeur |
|---|---|
time.Nanosecond | 1 |
time.Microsecond | 1000 ns |
time.Millisecond | 1000 µs |
time.Second | 1000 ms |
time.Minute | 60 s |
time.Hour | 60 min |
Il n'y a pas de time.Day, parce qu'une journée ne fait pas toujours 24 heures quand un fuseau horaire passe à l'heure d'été. Utilisez AddDate pour les jours calendaires (voir plus bas).
Deux bugs courants viennent du fait que Duration est un entier :
time.Sleep(5)dort 5 nanosecondes. Multipliez toujours par une unité :time.Sleep(5 * time.Second).time.Sleep(n * time.Second)ne compile pas quandnest une variableint. Convertissez-la :time.Duration(n) * time.Second. Une constante comme5fonctionne sans conversion parce que les constantes non typées s'adaptent au type Duration.
ParseDuration accepte ns, us (ou µs), ms, s, m et h, combinés comme "2h45m" ou "1.5s". Il n'a pas d'unité pour les jours.
Formatage : la disposition de référence 2006-01-02
Go n'utilise ni %Y-%m-%d ni yyyy-MM-dd. Une disposition (layout) est l'heure de référence
Mon Jan 2 15:04:05 MST 2006
écrite comme vous voulez que votre sortie apparaisse. Les valeurs sont choisies pour que chacune soit unique : mois 1, jour 2, heure 3 (ou 15), minute 4, seconde 5, année 6 (2006), décalage horaire -7 (-0700). Lisez-la comme 01/02 03:04:05PM '06 -0700.
Les éléments de disposition dont vous aurez le plus besoin :
| Élément | Signification | Exemple |
|---|---|---|
2006 / 06 | année, sur 4 ou 2 chiffres | 2026 / 26 |
01 / 1 / Jan / January | mois | 03 / 3 / Mar / March |
02 / 2 / _2 | jour du mois (complété par zéro, simple, complété par espace) | 05 / 5 / " 5" |
Mon / Monday | jour de la semaine | Thu / Thursday |
15 | heure, horloge de 24 heures | 09 |
03 / 3 | heure, horloge de 12 heures | 09 / 9 |
04 / 4 | minute | 07 / 7 |
05 / 5 | seconde | 03 / 3 |
PM / pm | marqueur AM ou PM | AM |
.000 / .999 | fractions de seconde (fixes / zéros finaux retirés) | .250 / .25 |
MST | abréviation du fuseau | UTC |
-0700 / -07:00 | décalage horaire numérique | +0000 / +00:00 |
Z07:00 | comme -07:00, mais affiche Z pour l'UTC | Z |
Dispositions prédéfinies :
| Constante | Disposition |
|---|---|
time.RFC3339 | 2006-01-02T15:04:05Z07:00 (à utiliser pour les API et le JSON) |
time.RFC3339Nano | 2006-01-02T15:04:05.999999999Z07:00 |
time.DateTime (Go 1.20) | 2006-01-02 15:04:05 |
time.DateOnly (Go 1.20) | 2006-01-02 |
time.TimeOnly (Go 1.20) | 15:04:05 |
time.Kitchen | 3:04PM |
time.RFC1123 | Mon, 02 Jan 2006 15:04:05 MST (les dates HTTP utilisent plutôt http.TimeFormat) |
L'erreur classique consiste à écrire une disposition avec les mauvais chiffres, par exemple "2023-01-01". Go ne la rejette pas. Il recopie les caractères qu'il ne reconnaît pas et remplace ceux qu'il reconnaît : chaque 2 est le jour, 3 est l'heure sur 12 heures et les deux 01 sont le mois, donc le 5 mars à 9 h 07 s'affiche 5059-03-03. Une disposition comme "YYYY-MM-DD" ne contient aucun élément et s'affiche telle quelle. Si des dates formatées ont l'air étranges, vérifiez que la disposition utilise exactement les valeurs de référence.
Parser des chaînes en instants
time.Parse(layout, value) utilise les mêmes dispositions, et renvoie une erreur que vous devez vérifier :
Sans fuseau dans l'entrée, Parse renvoie de l'UTC. La même chaîne d'heure locale peut désigner des instants différents selon le fuseau, c'est pourquoi ParseInLocation existe. Le message d'erreur nomme la partie qui n'a pas correspondu, ce qui aide quand vous déboguez une disposition.
Fuseaux horaires
Un time.Time est un instant plus une localisation utilisée pour l'affichage. Changer la localisation avec In change la façon dont il s'affiche, pas l'instant qu'il représente.
time.UTCest toujours disponible. Stockez et transmettez les instants en UTC (ou en RFC 3339 avec un décalage) et ne convertissez que pour l'affichage.time.Localest le fuseau de la machine. Sur les serveurs et dans les conteneurs, c'est souvent l'UTC, et sur un portable ce n'est pas le cas, donc le code qui en dépend se comporte différemment selon l'endroit.time.LoadLocation("Europe/Berlin")lit la base IANA du système d'exploitation. Les images de conteneur minimales ne l'ont souvent pas, et l'appel renvoie alors une erreur. L'import blanc_ "time/tzdata"intègre la base dans votre binaire (environ 450 Ko) pour que cela fonctionne toujours. Gérez toujours l'erreur.time.FixedZone(name, offsetSeconds)crée un fuseau avec un décalage constant. Il n'a pas de règles d'heure d'été, donc utilisez-le pour des décalages que vous avez reçus, pas pour des régions nommées.
Arithmétique et comparaison
À remarquer dans la sortie :
AddDate(0, 1, 0)sur le 31 janvier donne le 3 mars, pas le 28 février. Go ajoute un mois pour obtenir « 31 février » puis normalise le dépassement. Si vous avez besoin de « même jour le mois suivant, borné », écrivez cette logique vous-même.Subrenvoie uneDuration, qui plafonne à environ 292 ans. Pour des différences en jours calendaires, comparez des dates à minuit UTC et divisez par 24 heures.- Pour obtenir le début de la journée, reconstruisez l'instant à partir de
Date().t.Truncate(24 * time.Hour)arrondit par rapport à l'instant zéro en UTC, donc donne une mauvaise réponse pour tout fuseau autre que l'UTC.
Comparez avec Equal, Before, After, jamais avec ==. time.Now() inclut une lecture de l'horloge monotone, utilisée pour que time.Since reste correct si l'horloge murale est ajustée. == compare aussi cette lecture et la localisation, donc deux valeurs Time du même instant peuvent être inégales. Pour la même raison, n'utilisez pas time.Time comme clé de map sans le normaliser d'abord (t.UTC().Round(0) retire la lecture monotone).
Le time.Time zéro est le 1er janvier de l'an 1, 00:00 UTC. Testez-le avec t.IsZero().
Mesurer le temps écoulé
start := time.Now()
doWork()
log.Printf("doWork took %v", time.Since(start))
time.Since(start) équivaut à time.Now().Sub(start), et time.Until(deadline) à deadline.Sub(time.Now()). Les deux utilisent l'horloge monotone quand elle est disponible, donc ils résistent aux changements de l'horloge système. Pour mesurer les performances du code, utilisez les benchmarks du package testing plutôt qu'un chronométrage à la main.
Timers et tickers
time.After(d) renvoie un channel qui reçoit une fois après d. Un time.Timer est la même chose avec une méthode Stop. Un time.Ticker fournit une valeur à chaque période jusqu'à ce que vous l'arrêtiez.
Les trois ticks à 20, 40 et 60 ms arrivent bien avant le timer de 110 ms, donc le programme s'arrête après le troisième tick. time.AfterFunc(d, f) exécute f dans sa propre goroutine après d, ce qui est pratique pour un travail différé ponctuel.
Depuis Go 1.23, les timers et tickers qui ne sont plus référencés sont récupérés par le ramasse-miettes même si vous n'appelez jamais Stop, et le channel d'un timer arrêté ou réinitialisé ne fournit plus de valeur périmée. Appeler Stop avec defer reste la façon claire de dire que la vie du ticker est terminée. Quand une limite de temps s'applique à toute une opération plutôt qu'à une seule attente, un context.WithTimeout se lit généralement mieux qu'un timer.
Le temps en JSON
time.Time se sérialise automatiquement en JSON vers et depuis des chaînes RFC 3339, avec une précision à la nanoseconde :
type Event struct {
Name string `json:"name"`
At time.Time `json:"at"`
}
// {"name":"deploy","at":"2026-09-23T14:30:00Z"}
Une chaîne JSON dans un autre format échoue à la désérialisation. Pour des timestamps Unix ou des formats personnalisés, stockez un int64 ou une chaîne et convertissez, ou définissez un type avec son propre UnmarshalJSON.
Erreurs courantes
time.Sleep(1)outime.Sleep(n)avec un nombre seul. Ce sont des nanosecondes.- Des dispositions avec les mauvais chiffres.
"2023-01-01"ou"YYYY-MM-DD"ne sont pas des dispositions. Utilisez"2006-01-02". - Confondre minutes et mois. Les minutes sont
04, les mois01."15:01"affiche l'heure puis le mois, pas la minute. - Comparer avec
==. UtilisezEqual. - Compter sur
time.Local. Il diffère d'une machine à l'autre. Soyez explicite avectime.UTCou une localisation chargée. - Ignorer l'erreur de
LoadLocationou deParse. Les deux échouent sur de vraies entrées. UnParseen échec renvoie l'instant zéro, qui s'affiche comme l'an 1, et unLoadLocationen échec renvoie une localisationnilqui fait paniquert.In(loc).
Questions fréquentes
Comment faire une pause (sleep) en Go ?
Appelez time.Sleep avec un time.Duration : time.Sleep(2 * time.Second) ou time.Sleep(500 * time.Millisecond). Un nombre seul comme time.Sleep(2) compile mais dort 2 nanosecondes, parce qu'une Duration compte des nanosecondes. Sleep ne bloque que la goroutine courante.
Pourquoi Go utilise-t-il 2006-01-02 15:04:05 pour les formats de date ?
Go formate les dates par l'exemple. La disposition est l'heure de référence Mon Jan 2 15:04:05 MST 2006 écrite comme vous voulez que votre sortie apparaisse. Ses parties se suivent dans l'ordre américain : mois 1, jour 2, heure 3 (15 sur une horloge de 24 heures), minute 4, seconde 5, année 6 (2006), décalage horaire 7 (-0700). Donc "2006-01-02" signifie année-mois-jour et "02/01/2006" signifie jour/mois/année.
Comment parser une chaîne de date en Go ?
Utilisez time.Parse(layout, value) avec une disposition écrite à partir de l'heure de référence : t, err := time.Parse("2006-01-02", "2026-09-23"). Vérifiez toujours err. Sans information de fuseau dans la chaîne, le résultat est en UTC ; utilisez time.ParseInLocation pour l'interpréter dans un autre fuseau.
Comment obtenir un timestamp Unix en Go ?
time.Now().Unix() renvoie les secondes écoulées depuis le 1er janvier 1970 UTC sous forme de int64. UnixMilli(), UnixMicro() et UnixNano() donnent des unités plus fines. Pour la conversion inverse, utilisez time.Unix(sec, 0) ou time.UnixMilli(ms).
Comment comparer deux instants en Go ?
Utilisez t1.Before(t2), t1.After(t2) et t1.Equal(t2). N'utilisez pas == : il compare aussi la localisation et la lecture de l'horloge monotone, donc deux valeurs du même instant peuvent être inégales. t2.Sub(t1) donne la différence sous forme de Duration.