Le temps, une notion délicate : pourquoi les développeurs Swift perdent la tête
\n\nAvez-vous déjà envoyé une notification push qui est arrivée à l'utilisateur à 3 heures du matin ? Ou calculé une échéance pour une équipe internationale, pour la voir se décaler d'une journée ? Bienvenue dans l'univers des fuseaux horaires — ce domaine de la programmation où un simple « Z » manquant dans une chaîne peut anéantir toute la logique de votre application.
\n\nEn Swift, la gestion des fuseaux horaires ne se limite pas à un simple appel à Date(). C'est tout un écosystème de classes : Date, TimeZone, DateFormatter, Calendar et DateComponents. Si vous ne les maîtrisez pas dès le départ, votre projet se transformera en cauchemar de bugs qui ne se reproduisent que chez les utilisateurs de certaines régions.
Dans cet article, nous allons décortiquer la gestion des fuseaux horaires en Swift : du simple formatage aux scénarios complexes avec le passage à l'heure d'été. Vous apprendrez à ne pas vous tromper avec l'UTC, pourquoi Date n'est qu'un timestamp, et comment faire fonctionner votre application correctement aux quatre coins du monde.
Date en Swift : le piège du débutant
\n\nLa première chose à retenir : Date en Swift n'est ni une date ni une heure. C'est simplement le nombre de secondes écoulées depuis le 1er janvier 2001 à 00:00:00 UTC (date de référence). En elle-même, Date ne connaît ni les fuseaux horaires ni les calendriers. C'est un timestamp absolu.
\n\nVoici l'erreur classique du débutant :
\n\nlet now = Date()\nprint(now) // "2025-03-15 14:30:00 +0000" — c'est l'UTC, pas votre heure locale !\n\n\nQuand vous affichez Date dans la console, Xcode la montre en UTC. Mais l'utilisateur la voit dans son propre fuseau horaire. Le problème, c'est que beaucoup de débutants pensent que Date « connaît » déjà leur heure locale. Non. Date n'est qu'un nombre. Tout le reste n'est qu'interprétation.
Comment obtenir correctement l'heure actuelle dans le fuseau souhaité
\n\nPour travailler avec une heure « humaine », il faut utiliser DateFormatter et TimeZone. Voici un exemple minimal fonctionnel :
let dateFormatter = DateFormatter()\ndateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"\ndateFormatter.timeZone = TimeZone(identifier: "Europe/Paris")\n\nlet now = Date()\nlet parisTime = dateFormatter.string(from: now)\nprint("Il est actuellement à Paris : \\(parisTime)")\n\n\nRetenez cette règle : stockez les dates en UTC, affichez-les dans le fuseau local. Si vous enregistrez en base de données une chaîne comme « 2025-03-15 14:30:00 » sans indication de fuseau horaire, vous créez une bombe à retardement. Ajoutez toujours le décalage ou utilisez l'ISO 8601 avec le suffixe « Z » ou « +03:00 ».
\n\nTimeZone : votre meilleur allié et pire ennemi
\n\nLa classe TimeZone en Swift est une interface vers la base de données des fuseaux horaires IANA (base Olson). Elle contient les informations sur le passage à l'heure d'été, les changements historiques et les zones géographiques.
Les méthodes les plus courantes pour créer un TimeZone :
\n\n- \n
- Par identifiant (recommandé) :
TimeZone(identifier: "America/New_York")\n - Par abréviation (peu fiable) :
TimeZone(abbreviation: "EST")— peut confondre heure d'été/hiver \n - Par décalage GMT :
TimeZone(secondsFromGMT: 10800)— ignore l'heure d'été \n - Fuseau système actuel :
TimeZone.current\n
Voici un exemple montrant pourquoi les abréviations sont dangereuses :
\n\nlet est = TimeZone(abbreviation: "EST") // Heure normale de l'Est (UTC-5)\nlet edt = TimeZone(abbreviation: "EDT") // Heure avancée de l'Est (UTC-4)\n\n// Mais si vous utilisez EST en juillet, vous obtiendrez une heure erronée !\n// Il est préférable d'utiliser "America/New_York" — il gère automatiquement l'heure d'été\n\n\nUtilisez toujours les identifiants IANA — ils prennent en compte l'historique et le passage à l'heure d'été. C'est crucial pour les applications,