DateIntervalFormatter est une classe Foundation sous iOS et macOS conçue pour formater les plages de dates en chaînes localisées : « 21–25 juillet 2024 », « du 21 au 25 juillet 2024 » ou « Jul 21–25, 2024 ». Selon Apple Developer Documentation, 2024, DateIntervalFormatter détermine automatiquement quels composants de date répéter (si la plage est dans un même mois, le mois est affiché une fois) et localise les séparateurs et l'ordre des mots. Contrairement à la concaténation manuelle de deux dates formatées, cette classe prend en compte les règles grammaticales de la langue. La classe est disponible depuis iOS 8 et macOS 10.10.
Points clés
DateIntervalFormatter est une sous-classe de Formatter dans Foundation qui prend un objet DateInterval (une plage entre deux dates) et retourne une chaîne localisée décrivant cette plage. Par exemple, pour la plage du 21 au 25 juillet 2024, le résultat serait « 21–25 juillet 2024 » pour fr_FR. La classe regroupe intelligemment les éléments répétés : si les deux dates sont dans le même mois, le nom du mois est affiché une fois.
La valeur principale de DateIntervalFormatter est la gestion automatique de la grammaire des plages. Lors du formatage manuel, un développeur devrait comparer le mois/l'année de début et de fin, choisir un séparateur (tiret, « au », « bis ») et gérer la déclinaison. DateIntervalFormatter fait cela automatiquement sur la base des données CLDR (Common Locale Data Repository), réduisant les bugs dans les applications internationales, en particulier pour les langues à grammaire complexe.
Selon Unicode CLDR v44 (2024), les règles de formatage des intervalles de dates varient considérablement selon les langues. L'allemand utilise la préposition « bis » (21.–25. Juli 2024), le français utilise « au » (du 21 au 25 juillet 2024), le japonais utilise un trait d'union (2024 Jul 21–25). DateIntervalFormatter couvre toutes ces variations sans code supplémentaire du développeur.
Le principe de fonctionnement de DateIntervalFormatter est basé sur l'analyse de deux dates formant une plage et la sélection de la représentation textuelle optimale en tenant compte des paramètres régionaux. La classe compare les composants de date (année, mois, jour) et prend des décisions de regroupement : si l'année est identique, elle est affichée une fois ; si le mois est identique, il est affiché une fois ; si les jours diffèrent, une plage de jours est affichée.
| Plage | fr_FR |
|---|---|
| Un jour | 21 juillet 2024 |
| Dans le mois | 21–25 juillet 2024 |
| Mois différents | 21 juillet – 5 août 2024 |
| Années différentes | 25 décembre 2024 – 5 janvier 2025 |
| Avec heure | 21 juillet 2024, 14:30–16:45 |
Logique de regroupement implémentée sur la base de modèles CLDR. Le formatteur vérifie l'égalité de chaque composant de date (Calendar.Component : year, month, day) dans l'ordre du plus grand au plus petit. Une fois qu'un composant diffère, tous les composants plus petits sont affichés pour les deux dates. Par exemple, pour le 21–25 juillet : année correspond, mois correspond, jour diffère → le mois est affiché une fois, les jours sont affichés pour chaque date.
Note importante : DateIntervalFormatter ne permet pas de personnaliser le séparateur via l'API. Le séparateur est déterminé par les paramètres régionaux et ne peut pas être remplacé. Si un séparateur non standard est nécessaire (par exemple, « à » au lieu de « au »), vous devrez formater les dates manuellement avec DateFormatter et concaténer les chaînes avec un séparateur personnalisé.
DateIntervalFormatter fournit deux ensembles de styles : dateStyle et timeStyle pour chaque extrémité de la plage. Ces styles fonctionnent de manière similaire à DateFormatter : .none masque le composant, .short donne un format court (21/07/2024), .medium (21 juill. 2024), .long (21 juillet 2024), .full (dimanche 21 juillet 2024). En combinant dateStyle et timeStyle, différents niveaux de détail peuvent être obtenus.
Important : dateStyle et timeStyle s'appliquent aux deux extrémités de la plage de manière égale. Vous ne pouvez pas définir des styles différents pour le début et la fin (par exemple, .medium pour le début et .short pour la fin). Si des styles différents sont nécessaires, vous devez formater chaque date avec un DateFormatter séparé et concaténer les résultats.
import Foundation
let formatter = DateIntervalFormatter()
// Différentes combinaisons de styles
let startDate = Date()
let endDate = Date().addingTimeInterval(345600) // +4 jours
let interval = DateInterval(start: startDate, end: endDate)
// Date uniquement, format moyen
formatter.dateStyle = .medium
formatter.timeStyle = .none
print("Date uniquement : \(formatter.string(from: interval))")
// Format court avec heure
formatter.dateStyle = .short
formatter.timeStyle = .short
print("Court avec heure : \(formatter.string(from: interval))")
// Format complet
formatter.dateStyle = .full
formatter.timeStyle = .none
print("Date complète : \(formatter.string(from: interval))")
Utilisation de base de DateIntervalFormatter inclut la création d'une instance, la définition des styles et l'appel de string(from:). La méthode accepte DateInterval, une structure avec les propriétés start et end. DateInterval peut être créé à partir de deux valeurs Date ou initialisé avec Duration (iOS 16+). Après le formatage, le résultat est prêt pour l'affichage dans l'interface sans traitement supplémentaire.
import Foundation
let calendar = Calendar.current
let now = Date()
// Exemples d'intervalles spécifiques
let examples: [(title: String, start: Date, end: Date)] = [
(
"2-hour event",
now,
now.addingTimeInterval(7200)
),
(
"Week-long vacation",
now,
now.addingTimeInterval(604800)
),
(
"Cross-year period",
calendar.date(from: DateComponents(
year: 2024, month: 12, day: 25
))!,
calendar.date(from: DateComponents(
year: 2025, month: 1, day: 5
))!
)
]
let intervalFormatter = DateIntervalFormatter()
intervalFormatter.dateStyle = .medium
intervalFormatter.timeStyle = .short
for (title, start, end) in examples {
let interval = DateInterval(start: start, end: end)
let result = intervalFormatter.string(from: interval)
print("\(title): \(result)")
}
// Format via Calendar (iOS 16+)
if let nextWeek = calendar.date(
byAdding: .day, value: 7, to: now
) {
let weekInterval = DateInterval(start: now, end: nextWeek)
print("7 prochains jours : \(intervalFormatter.string(from: weekInterval))")
}
DateIntervalFormatter et réservation de calendrier : dans les applications de réservation (hôtels, billets), les intervalles de dates sont un élément clé de l'interface. DateIntervalFormatter gère correctement les intervalles sur plusieurs années (par exemple, du 28 décembre au 3 janvier), en regroupant le mois et l'année pour chaque date séparément. Pour de tels scénarios, il est recommandé d'utiliser dateStyle = .medium et timeStyle = .none, le format le plus lisible pour les dates sans heure.
import Foundation
let formatter = DateIntervalFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .none
// Exemples de réservation
struct Booking {
let checkIn: Date
let checkOut: Date
var formattedInterval: String {
let interval = DateInterval(start: checkIn, end: checkOut)
return formatter.string(from: interval)
}
}
let booking = Booking(
checkIn: calendar.date(from: DateComponents(
year: 2024, month: 7, day: 21
))!,
checkOut: calendar.date(from: DateComponents(
year: 2024, month: 7, day: 25
))!
)
print("Réservation : \(booking.formattedInterval)")
// Utiliser avec différents paramètres régionaux
let enFormatter = DateIntervalFormatter()
enFormatter.dateStyle = .medium
enFormatter.timeStyle = .none
enFormatter.locale = Locale(identifier: "en_US")
print("Anglais : \(enFormatter.string(from: interval))")
DateInterval vs DateIntervalFormatter : DateInterval est une structure représentant une plage de dates (début et fin). DateIntervalFormatter est un formatteur qui convertit cette structure en chaîne. DateInterval prend également en charge les vérifications contains(Date) et intersection(with:), utiles pour la logique de réservation (vérification de chevauchement de dates).
DateIntervalFormatter localise la sortie via la propriété locale. Par défaut, Locale.current est utilisé, les paramètres régionaux de l'appareil. Pour afficher des intervalles dans une autre langue (par exemple, contenu en anglais avec interface française), définissez explicitement la locale. Contrairement à DateFormatter, DateIntervalFormatter ne nécessite pas de définition de locale pour les données côté serveur. Il utilise toujours sa logique de regroupement interne basée sur CLDR.
Les différences linguistiques dans le formatage des intervalles de dates sont considérablement plus complexes que pour les dates individuelles. Le français utilise la préposition « au » : du 21 au 25 juillet. L'anglais utilise un simple tiret : Jul 21–25. L'allemand utilise un point après le nombre et un tiret : 21.–25. Juli. DateIntervalFormatter couvre toutes ces variantes.
import Foundation
let formatter = DateIntervalFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
let start = Date()
let end = Date().addingTimeInterval(259200) // +3 jours
let interval = DateInterval(start: start, end: end)
// Montrer différents paramètres régionaux
let localeIds = ["ru_RU", "en_US", "de_DE", "fr_FR", "ja_JP", "zh_CN"]
for localeId in localeIds {
formatter.locale = Locale(identifier: localeId)
print("\(localeId): \(formatter.string(from: interval))")
}
// Localisation des intervalles de temps
formatter.dateStyle = .none
formatter.timeStyle = .short
let todayStart = Date()
let todayEnd = Date().addingTimeInterval(3600)
let timeInterval = DateInterval(start: todayStart, end: todayEnd)
for localeId in ["ru_RU", "en_US", "de_DE"] {
formatter.locale = Locale(identifier: localeId)
print("\(localeId) heure : \(formatter.string(from: timeInterval))")
}
Spécificités de localisation : pour le français, DateIntervalFormatter utilise les prépositions « du » et « au » pour les formats longs. Pour les formats courts, il utilise le tiret. Le choix du format dépend du contexte : pour une liste de réservations utilisez .medium, pour une vue détaillée utilisez .long ou .full.
DateIntervalFormatter occupe le créneau du formatage des plages de dates, qui n'est pas couvert par les autres classes Foundation. DateFormatter formate les dates individuelles, RelativeDateTimeFormatter formate les dates relatives (il y a/dans), DateComponentsFormatter formate la durée (2 heures 30 minutes). Chacune de ces classes résout une tâche spécifique et ne peuvent pas être utilisées de manière interchangeable.
| Classe | Objectif | Exemple de sortie |
|---|---|---|
| DateIntervalFormatter | Plage de dates | 21–25 juillet 2024 |
| DateFormatter | Date individuelle | 21 juillet 2024 |
| RelativeDateTimeFormatter | Temps relatif | il y a 3 jours |
| DateComponentsFormatter | Durée | 2 heures 30 minutes |
| ISO8601DateFormatter | Format ISO 8601 | 2024-07-21T14:30:00Z |
Quand utiliser DateIntervalFormatter : pour afficher des plages de dates dans l'interface — réservations d'hôtels, événements, filtrage par dates, historique des opérations. Pour calculer la durée entre des dates, utilisez DateComponentsFormatter, pas DateIntervalFormatter, ce dernier n'étant pas conçu pour afficher la durée. DateFormatter ne doit être utilisé que pour les dates individuelles, pas pour concaténer deux dates formatées via une concaténation de chaînes, car cela entraîne une perte de localisation du séparateur.
Cas limite : DateIntervalFormatter ne prend pas en charge l'affichage des intervalles ouverts (sans date de fin). Si la fin de la plage est inconnue (par exemple, « depuis le 21 juillet »), utilisez DateFormatter avec la préposition « depuis ». De plus, DateIntervalFormatter ne prend pas en charge les intervalles avec heure spécifiée pour des jours différents. L'heure est appliquée à chaque date séparément, ce qui peut sembler redondant pour les intervalles courts.
Foire aux questions
DateIntervalFormatter est une classe Foundation pour formater les plages de dates en chaînes localisées. Disponible depuis iOS 8, il regroupe automatiquement les composants répétés (mois, année) et sélectionne le séparateur correct pour la langue.
Il compare les composants de l'année au jour. Si l'année correspond, elle est affichée une fois. Si le mois correspond, il est affiché une fois. Les jours différents sont affichés comme une plage. Cela donne « 21–25 juillet 2024 » au lieu de « 21 juillet 2024 – 25 juillet 2024 ».
Non, le séparateur est déterminé par les paramètres régionaux et ne peut pas être personnalisé via l'API. Pour un séparateur personnalisé (par exemple, « à » au lieu de « au »), formatez chaque date avec un DateFormatter séparé et concaténez les chaînes manuellement.
DateIntervalFormatter formate une plage de dates (deux dates) comme une unité unique avec regroupement de composants. DateFormatter formate une date individuelle. Pour les plages, utilisez toujours DateIntervalFormatter car il fournit une localisation correcte du séparateur.
Automatiquement — DateIntervalFormatter détecte que les années diffèrent et affiche les dates complètes pour les deux extrémités : « 25 décembre 2024 – 5 janvier 2025 ». Aucune configuration supplémentaire n'est requise, il suffit de définir dateStyle.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi