Zero value time.Time en Go : pièges qui tuent votre code

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : Le bug que tout le monde a déjà rencontré

\n\n

Avez-vous déjà vu dans vos logs la date 0001-01-01 00:00:00 +0000 UTC en vous demandant : « D'où ça sort ? Je n'ai rien initialisé ! » ? Félicitations, vous avez rencontré le zero value de time.Time en Go. C'est un piège classique qui cumule des milliers de vues sur Stack Overflow et des centaines d'heures de débogage dans le monde entier.

\n\n

Dans cet article, nous allons voir ce qu'est le zero value pour time.Time, pourquoi il se comporte de manière inattendue, comment distinguer une date « vide » d'une date réelle et, surtout, comment éviter ces pièges en production. Si vous codez en Go et manipulez des dates, ce contenu vous évitera bien des maux de tête.

\n\n

Qu'est-ce que le zero value en Go et pourquoi time.Time est un cas particulier

\n\n

En Go, chaque type a une valeur nulle (zero value). Pour les nombres, c'est 0, pour les chaînes, "", pour les pointeurs, nil. La logique est simple : si vous déclarez une variable sans l'initialiser, elle reçoit une valeur « vide ». Mais avec time.Time, c'est plus complexe.

\n\n

Le zero value de time.Time n'est pas le timestamp Unix 0 (1970-01-01), comme on pourrait s'y attendre. C'est 0001-01-01 00:00:00 +0000 UTC. Pourquoi ? Parce qu'en interne, time.Time stocke les nanosecondes depuis le 1er janvier de l'an 1 (calendrier grégorien). Zéro dans cette représentation donne l'an 1.

\n\n
package main\n\nimport (\n    "fmt"\n    "time"\n)\n\nfunc main() {\n    var t time.Time\n    fmt.Println(t) // 0001-01-01 00:00:00 +0000 UTC\n    fmt.Println(t.Unix()) // -62135596800 (nombre négatif !)\n}\n
\n\n

Vous voyez déjà le problème ? Si vous essayez de vérifier if t == 0 ou de comparer avec le zéro Unix, votre code va casser. Passons en revue le top des erreurs avec le zero value de time.Time et les solutions pour les éviter.

\n\n

Top 5 des erreurs avec le zero value de time.Time

\n\n

1. Comparaison avec le timestamp Unix 0

\n\n

L'erreur la plus courante : essayer de vérifier si une date est « vide » en la comparant à time.Unix(0, 0). Cela ne fonctionne pas, car le zero value n'est pas l'année 1970.

\n\n
// ❌ Erreur : ne sera jamais true\nvar t time.Time\nif t == time.Unix(0, 0) {\n    fmt.Println("Date vide")\n}\n\n// ✅ Correct : utiliser la méthode IsZero()\nif t.IsZero() {\n    fmt.Println("Date vide")\n}\n
\n\n

La méthode IsZero() est votre outil principal. Elle retourne true uniquement pour le zero value, pas pour n'importe quelle date « ancienne ».

\n\n

2. Sérialisation en JSON : un null inattendu

\n\n

Lorsque vous sérialisez une structure contenant time.Time en JSON, le zero value devient la chaîne "0001-01-01T00:00:00Z". Cela casse votre API, votre frontend et vos bases de données. Les clients voient une date étrange, pas un null.

\n\n
type Event struct {\n    Name      string    `json:"name"`\n    StartTime time.Time `json:"start_time"`\n}\n\nfunc main() {\n    e := Event{Name: "test"}\n    data, _ := json.Marshal(e)\n    fmt.Println(string(data))\n    // {"name":"test","start_time":"0001-01-01T00:00:00Z"}\n    // ❌ Devrait être null ou le champ devrait être absent\n}\n
\n\n

Solution : utilisez un pointeur vers time.Time (*time.Time) ou un type personnalisé avec une logique de sérialisation.

\n\n
// ✅ Solution avec pointeur\ntype Event struct {\n    Name      string     `json:"name"`\n    StartTime *time.Time `json:"start_time,omitempty"`\n}\n\n// ✅ Ou un type personnalisé avec omitempty\ntype CustomTime struct {\n    time.Time\n}\n\nfunc (ct CustomTime) MarshalJSON() ([]byte, error) {\n    if ct.IsZero() {\n        return []byte("null"), nil\n    }\n    return json.Marshal(ct.Time)\n}\n
\n\n

3. Problèmes avec les bases de données (SQL)

\n\n

En insérant un time.Time nul dans PostgreSQL ou MySQL, vous obtiendrez la date 0001-01-01, ce qui provoquera une erreur de contrainte de plage (l'an 1 est en dehors de la plage valide).

Blogs

Book Recommendations