Travail avec les dates et l'heure en Swift : techniques avancées

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

Travail avancé avec les dates et l'heure en Swift : des bases à l'optimisation

\n

Travailler avec les dates et l'heure est l'une des tâches les plus fréquentes et les plus délicates en développement iOS/macOS. La simplicité apparente de l'API Foundation (Date, DateFormatter, Calendar) conduit souvent à des erreurs liées aux fuseaux horaires, à la localisation ou aux performances. Dans cet article, nous allons explorer les techniques avancées de travail avec les dates en Swift : du parsing correct aux calculs haute performance utiles dans les projets de production.

\n\n

1. DateFormatter : réglage fin et mise en cache

\n

L'erreur la plus courante des débutants est de créer un nouvel objet DateFormatter à l'intérieur d'une boucle ou d'une méthode fréquemment appelée. La création d'un DateFormatter est une opération coûteuse (jusqu'à 1000 fois plus lente que sa réutilisation).

\n\n
// ❌ Mauvais : création d'un formatter à chaque fois\nfunc parseDate(from string: String) -> Date? {\n    let formatter = DateFormatter()\n    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"\n    formatter.locale = Locale(identifier: "ru_RU")\n    formatter.timeZone = TimeZone(secondsFromGMT: 0)\n    return formatter.date(from: string)\n}\n\n// ✅ Bon : mise en cache du formatter\nprivate let isoDateFormatter: DateFormatter = {\n    let f = DateFormatter()\n    f.dateFormat = "yyyy-MM-dd HH:mm:ss"\n    f.locale = Locale(identifier: "ru_RU")\n    f.timeZone = TimeZone(secondsFromGMT: 0)\n    return f\n}()\n\nfunc parseDateFast(from string: String) -> Date? {\n    return isoDateFormatter.date(from: string)\n}
\n\n

Conseil avancé : Pour travailler avec des formats fixes (par exemple, ISO 8601), utilisez ISO8601DateFormatter — il est plus rapide que le DateFormatter standard. Pour les formats personnalisés nécessitant des performances élevées, envisagez d'utiliser DateFormatter avec un stockage thread-local :

\n\n
extension DateFormatter {\n    static let threadLocal: ThreadLocal<DateFormatter> = ThreadLocal {\n        let f = DateFormatter()\n        f.dateFormat = "dd.MM.yyyy"\n        f.locale = Locale(identifier: "ru_RU")\n        return f\n    }\n}
\n\n

2. Calendar et DateComponents : calculs sans erreurs

\n

Pour l'arithmétique des dates (ajouter un jour, trouver le début du mois), utilisez Calendar plutôt que l'addition manuelle de secondes. L'ajout manuel de 86400 secondes (24*60*60) échoue lors du passage à l'heure d'été.

\n\n
let calendar = Calendar.current\nlet now = Date()\n\n// ✅ Ajout sécurisé d'un jour\nif let tomorrow = calendar.date(byAdding: .day, value: 1, to: now) {\n    print("Demain : \\(tomorrow)")\n}\n\n// ✅ Trouver le début du mois en cours\nlet startOfMonth = calendar.date(from: calendar.dateComponents([.year, .month], from: now))!\n\n// ✅ Obtenir les composants en tenant compte de la locale\nlet components = calendar.dateComponents([.weekday, .weekOfYear], from: now)\nprint("Jour de la semaine : \\(components.weekday ?? 0)") // 1 = dimanche aux États-Unis, 2 = lundi en France
\n\n

Conseil avancé : Pour les calculs à forte charge (par exemple, la génération d'une grille de calendrier), mettez en cache Calendar et TimeZone. Évitez d'utiliser Calendar.current dans les boucles — il sollicite les paramètres système à chaque fois.

\n\n

3. Localisation et formatage pour l'utilisateur

\n

Ne montrez jamais une date brute à l'utilisateur. Utilisez DateFormatter avec des styles prédéfinis (.short, .medium, .long, .full) et RelativeDateTimeFormatter pour les dates relatives lisibles par l'humain ("hier", "il y a 3 jours").

\n\n
// Date absolue tenant compte de la locale de l'utilisateur\nlet userFormatter = DateFormatter()\nuserFormatter.dateStyle = .long\nuserFormatter.timeStyle = .short\nprint(userFormatter.string(from: Date())) // "15 juin 2025, 14:30" (pour fr_FR)\n\n// Date relative (iOS 13+)\nlet relativeFormatter = RelativeDateTimeFormatter()\nrelat                

Blogs

Book Recommendations