Το DateIntervalFormatter είναι μια κλάση Foundation στο iOS και macOS που προορίζεται για μορφοποίηση εύρους ημερομηνιών σε τοπικοποιημένες συμβολοσειρές: "21–25 Ιουλίου 2024", "από 21 έως 25 Ιουλίου 2024" ή "Jul 21–25, 2024". Σύμφωνα με Apple Developer Documentation, 2024, το DateIntervalFormatter καθορίζει αυτόματα ποια στοιχεία ημερομηνίας να επαναληφθούν (αν το εύρος είναι εντός ενός μήνα — ο μήνας εμφανίζεται μία φορά) και τοπικοποιεί τους διαχωριστές και τη σειρά λέξεων. Σε αντίθεση με τη χειροκίνητη σύνδεση δύο μορφοποιημένων ημερομηνιών, αυτή η κλάση λαμβάνει υπόψη τους γραμματικούς κανόνες: για τα ελληνικά — πρόθεση "έως", για τα αγγλικά — ενωτικό χωρίς πρόθεση. Η κλάση είναι διαθέσιμη από iOS 8 και macOS 10.10.
Βασικά σημεία
DateIntervalFormatter είναι μια υποκλάση του Formatter στο Foundation που δέχεται ένα αντικείμενο DateInterval (ένα εύρος μεταξύ δύο ημερομηνιών) και επιστρέφει μια τοπικοποιημένη συμβολοσειρά με περιγραφή αυτού του εύρους. Για παράδειγμα, για το εύρος από 21 έως 25 Ιουλίου 2024, το αποτέλεσμα θα είναι "21–25 Ιουλίου 2024" για el_GR και "Jul 21–25, 2024" για en_US. Η κλάση ομαδοποιεί έξυπνα τα επαναλαμβανόμενα στοιχεία: αν και οι δύο ημερομηνίες είναι στον ίδιο μήνα, το όνομα του μήνα εμφανίζεται μία φορά.
Η κύρια αξία του DateIntervalFormatter είναι η αυτόματη επεξεργασία της γραμματικής των ευρών. Στη χειροκίνητη μορφοποίηση, ο προγραμματιστής θα πρέπει να συγκρίνει τον μήνα/το έτος έναρξης και λήξης, να επιλέξει τον διαχωριστικό (ενωτικό, "από–έως", "to", "bis") και να παρακολουθήσει την κλίση. Το DateIntervalFormatter το κάνει αυτόματα βάσει των δεδομένων CLDR (Common Locale Data Repository), μειώνοντας έτσι τον αριθμό σφαλμάτων σε διεθνείς εφαρμογές, ειδικά για γλώσσες με σύνθετη γραμματική.
Σύμφωνα με Unicode CLDR v44 (2024), οι κανόνες μορφοποίησης εύρους ημερομηνιών διαφέρουν σημαντικά μεταξύ των γλωσσών. Τα γερμανικά χρησιμοποιούν την πρόθεση "bis" (21.–25. Juli 2024), τα γαλλικά — "au" (du 21 au 25 juillet 2024), τα ιαπωνικά — με ενωτικό (2024 Jul 21–25). Το DateIntervalFormatter καλύπτει όλες αυτές τις ποικιλίες χωρίς επιπλέον κώδικα από τον προγραμματιστή.
Αρχή λειτουργίας Το DateIntervalFormatter βασίζεται στην ανάλυση δύο ημερομηνιών που σχηματίζουν το εύρος και στην επιλογή της βέλτιστης κειμενικής αναπαράστασης λαμβάνοντας υπόψη το locale. Η κλάση συγκρίνει τα στοιχεία ημερομηνίας (έτος, μήνας, ημέρα) και λαμβάνει απόφαση για την ομαδοποίηση: αν το έτος είναι ίδιο — εμφανίζεται μία φορά· αν ο μήνας είναι ίδιος — εμφανίζεται μία φορά· αν οι ημέρες διαφέρουν — εμφανίζεται το εύρος ημερών.
| Εύρος | el_GR | en_US |
|---|---|---|
| Μία ημέρα | 21 Ιουλίου 2024 | Jul 21, 2024 |
| Εντός μήνα | 21–25 Ιουλίου 2024 | Jul 21–25, 2024 |
| Διαφορετικοί μήνες | 21 Ιουλίου – 5 Αυγούστου 2024 | Jul 21 – Aug 5, 2024 |
| Διαφορετικά έτη | 25 Δεκεμβρίου 2024 – 5 Ιανουαρίου 2025 | Dec 25, 2024 – Jan 5, 2025 |
| Με ώρα | 21 Ιουλίου 2024, 14:30–16:45 | Jul 21, 2024, 2:30–4:45 PM |
Λογική ομαδοποίησης εφαρμόζεται με βάση τα πρότυπα CLDR. Ο μορφοποιητής ελέγχει την ισότητα κάθε στοιχείου ημερομηνίας (Calendar.Component: year, month, day) σε σειρά από το μεγαλύτερο προς το μικρότερο. Μόλις ένα στοιχείο διαφέρει, όλα τα μικρότερα στοιχεία εμφανίζονται και για τις δύο ημερομηνίες. Παράδειγμα, για 21–25 Ιουλίου: το έτος ταιριάζει, ο μήνας ταιριάζει, η ημέρα διαφέρει → μήνας μία φορά, ημέρες — για κάθε ημερομηνία ξεχωριστά.
Σημαντική απόχρωση: Το DateIntervalFormatter δεν υποστηρίζει τη ρύθμιση του διαχωριστικού μέσω API. Ο διαχωριστικός καθορίζεται από το locale και δεν μπορεί να αντικατασταθεί. Εάν απαιτείται προσαρμοσμένος διαχωριστικός (για παράδειγμα, "έως" αντί για "–"), θα πρέπει να μορφοποιήσετε τις ημερομηνίες χειροκίνητα μέσω DateFormatter και να συνδέσετε τις συμβολοσειρές με τον προσαρμοσμένο διαχωριστικό.
DateIntervalFormatter παρέχει δύο σετ στυλ: dateStyle και timeStyle — για κάθε άκρο του εύρους. Αυτά τα στυλ λειτουργούν παρόμοια με το DateFormatter: .none κρύβει το στοιχείο, .short δίνει σύντομη μορφή (21.07.2024), .medium — μετρία (21 Ιουλ 2024), .long — μακρά (21 Ιουλίου 2024), .full — μέγιστη λεπτομέρεια (Κυριακή, 21 Ιουλίου 2024). Συνδυάζοντας dateStyle και timeStyle, μπορείτε να έχετε διαφορετικά επίπεδα λεπτομέρειας.
Σημαντικό: τα dateStyle και timeStyle εφαρμόζονται ισόποσα και στα δύο άκρα του εύρους. Δεν μπορείτε να ορίσετε διαφορετικό στυλ για την αρχή και το τέλος (για παράδειγμα, .medium για την αρχή και .short για το τέλος). Εάν απαιτείται διαφορετικό στυλ, πρέπει να μορφοποιήσετε κάθε ημερομηνία με ξεχωριστό DateFormatter και να συνδέσετε τα αποτελέσματα.
import Foundation
let formatter = DateIntervalFormatter()
// Διαφορετικοί συνδυασμοί στυλ
let startDate = Date()
let endDate = Date().addingTimeInterval(345600) // +4 ημέρες
let interval = DateInterval(start: startDate, end: endDate)
// Μόνο ημερομηνία, μεσαία μορφή
formatter.dateStyle = .medium
formatter.timeStyle = .none
print("Μόνο ημερομηνία: \(formatter.string(from: interval))")
// Σύντομη μορφή με ώρα
formatter.dateStyle = .short
formatter.timeStyle = .short
print("Σύντομη με ώρα: \(formatter.string(from: interval))")
// Πλήρης μορφή
formatter.dateStyle = .full
formatter.timeStyle = .none
print("Πλήρης ημερομηνία: \(formatter.string(from: interval))")
Βασική χρήση του DateIntervalFormatter περιλαμβάνει τη δημιουργία παραδείγματος, τη ρύθμιση των στυλ και την κλήση string(from:). Η μέθοδος δέχεται DateInterval — μια δομή με ιδιότητες start και end. Το DateInterval μπορεί να δημιουργηθεί και από δύο Date, αλλά και να αρχικοποιηθεί με Duration (iOS 16+). Μετά τη μορφοποίηση, το αποτέλεσμα είναι έτοιμο για εμφάνιση στο UI χωρίς επιπλέον επεξεργασία.
import Foundation
let calendar = Calendar.current
let now = Date()
// Παραδείγματα συγκεκριμένων διαστημάτων
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)")
}
// Μορφοποίηση μέσω Calendar (iOS 16+)
if let nextWeek = calendar.date(
byAdding: .day, value: 7, to: now
) {
let weekInterval = DateInterval(start: now, end: nextWeek)
print("Επόμενες 7 ημέρες: \(intervalFormatter.string(from: weekInterval))")
}
DateIntervalFormatter και Calendar Booking: σε εφαρμογές κρατήσεων (ξενοδοχεία, εισιτήρια) τα εύρη ημερομηνιών είναι βασικό στοιχείο του UI. Το DateIntervalFormatter επεξεργάζεται σωστά τα διαετή εύρη (για παράδειγμα, από 28 Δεκεμβρίου έως 3 Ιανουαρίου), ομαδοποιώντας τον μήνα και το έτος για κάθε ημερομηνία ξεχωριστά. Για τέτοια σενάρια, συνιστάται η χρήση dateStyle = .medium και timeStyle = .none — η πιο ευανάγνωστη μορφή για ημερομηνίες χωρίς ώρα.
import Foundation
let formatter = DateIntervalFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .none
// Παραδείγματα κρατήσεων
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("Κράτηση: \(booking.formattedInterval)")
// Χρήση με διαφορετικά locale
let enFormatter = DateIntervalFormatter()
enFormatter.dateStyle = .medium
enFormatter.timeStyle = .none
enFormatter.locale = Locale(identifier: "en_US")
print("Αγγλικά: \(enFormatter.string(from: interval))")
DateInterval vs DateIntervalFormatter: DateInterval — δομή που αντιπροσωπεύει ένα εύρος ημερομηνιών (αρχή και τέλος). DateIntervalFormatter — μορφοποιητής που μετατρέπει αυτή τη δομή σε συμβολοσειρά. Το DateInterval υποστηρίζει επίσης τους ελέγχους contains(Date) και intersection(with:), που είναι χρήσιμοι για τη λογική κρατήσεων (έλεγχος επικάλυψης ημερομηνιών).
DateIntervalFormatter τοπικοποιεί την έξοδο μέσω της ιδιότητας locale. Από προεπιλογή, χρησιμοποιείται Locale.current — το locale της συσκευής. Για να εμφανίσετε διαστήματα σε άλλη γλώσσα (για παράδειγμα, αγγλικό περιεχόμενο σε ελληνική διεπαφή), ορίστε ρητά το locale. Σε αντίθεση με το DateFormatter, το DateIntervalFormatter δεν απαιτεί ρύθμιση Locale για δεδομένα διακομιστή — χρησιμοποιεί πάντα τη δική του εσωτερική λογική ομαδοποίησης βάσει CLDR.
Οι γλωσσικές διαφορές στη μορφοποίηση ευρών ημερομηνιών είναι σημαντικά πιο περίπλοκες από ό,τι για μεμονωμένες ημερομηνίες. Τα αγγλικά χρησιμοποιούν απλό ενωτικό: Jul 21–25. Τα ελληνικά — πρόθεση "από–έως": από 21 έως 25 Ιουλίου. Τα γαλλικά — "au": du 21 au 25 juillet. Τα γερμανικά — τελεία μετά τον αριθμό και ενωτικό: 21.–25. Juli. Τα ιαπωνικά — με ενωτικό χωρίς πρόθεση: Jul 21–25. Το DateIntervalFormatter καλύπτει όλες αυτές τις παραλλαγές.
import Foundation
let formatter = DateIntervalFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
let start = Date()
let end = Date().addingTimeInterval(259200) // +3 ημέρες
let interval = DateInterval(start: start, end: end)
// Επίδειξη διαφορετικών locale
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))")
}
// Τοπικοποίηση για χρονικά διαστήματα
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) ώρα: \(formatter.string(from: timeInterval))")
}
Χαρακτηριστικά τοπικοποίησης: για τα ελληνικά, το DateIntervalFormatter χρησιμοποιεί προθέσεις "από" και "έως" για μακρές μορφές ημερομηνίας. Για σύντομη (short) μορφή — μόνο ενωτικό: 21.07–25.07.2024. Για πλήρη μορφή (full) — με αναφορά της ημέρας της εβδομάδας. Η επιλογή μορφής εξαρτάται από το περιβάλλον: για λίστα κρατήσεων χρησιμοποιήστε .medium, για λεπτομερή προβολή — .long ή .full.
DateIntervalFormatter καλύπτει την εξειδικευμένη περιοχή μορφοποίησης ευρών ημερομηνιών που άλλες κλάσεις Foundation δεν καλύπτουν. Το DateFormatter μορφοποιεί μεμονωμένες ημερομηνίες, το RelativeDateTimeFormatter — σχετικές ημερομηνίες (πριν/μετά), το DateComponentsFormatter — διάρκεια (2 ώρες 30 λεπτά). Κάθε μία από αυτές τις κλάσεις λύνει τη δική της εργασία και δεν μπορούν να αντικατασταθούν.
| Κλάση | Σκοπός | Παράδειγμα εξόδου |
|---|---|---|
| DateIntervalFormatter | Εύρος ημερομηνιών | 21–25 Ιουλίου 2024 |
| DateFormatter | Μεμονωμένη ημερομηνία | 21 Ιουλίου 2024 |
| RelativeDateTimeFormatter | Σχετικός χρόνος | 3 ημέρες πριν |
| DateComponentsFormatter | Διάρκεια | 2 ώρες 30 λεπτά |
| ISO8601DateFormatter | Μορφή ISO 8601 | 2024-07-21T14:30:00Z |
Πότε να χρησιμοποιείτε DateIntervalFormatter: για εμφάνιση ευρών ημερομηνιών στο UI — κράτηση ξενοδοχείων, εκδηλώσεις, φιλτράρισμα κατά ημερομηνία, ιστορικό λειτουργιών. Για υπολογισμό διάρκειας μεταξύ ημερομηνιών χρησιμοποιήστε DateComponentsFormatter, όχι DateIntervalFormatter — το δεύτερο δεν είναι σχεδιασμένο για εμφάνιση διάρκειας. Το DateFormatter πρέπει να χρησιμοποιείται μόνο για μεμονωμένες ημερομηνίες, όχι για σύνδεση δύο μορφοποιημένων ημερομηνιών μέσω συνένωσης συμβολοσειράς — αυτό οδηγεί σε απώλεια τοπικοποίησης του διαχωριστικού.
Ακραία περίπτωση: Το DateIntervalFormatter δεν υποστηρίζει εμφάνιση ανοικτών ευρών (χωρίς ημερομηνία λήξης). Εάν το τέλος του εύρους είναι άγνωστο (για παράδειγμα, "από 21 Ιουλίου"), χρησιμοποιήστε DateFormatter με πρόθεση "από" για τα ελληνικά ή "from" για τα αγγλικά. Το DateIntervalFormatter επίσης δεν υποστηρίζει εύρη με αναφορά ώρας για διαφορετικές ημέρες — η ώρα εφαρμόζεται σε κάθε ημερομηνία ξεχωριστά, που μπορεί να φαίνεται υπερβολικό για σύντομα εύρη.
Συχνές ερωτήσεις
DateIntervalFormatter — κλάση Foundation για μορφοποίηση εύρους ημερομηνιών σε τοπικοποιημένες συμβολοσειρές. Διαθέσιμη από iOS 8, ομαδοποιεί αυτόματα επαναλαμβανόμενα στοιχεία (μήνας, έτος) και επιλέγει τον σωστό διαχωριστικό για τη γλώσσα.
Συγκρίνει στοιχεία από έτος σε ημέρα. Αν το έτος ταιριάζει — εμφανίζεται μία φορά. Αν ο μήνας ταιριάζει — εμφανίζεται μία φορά. Οι διαφορετικές ημέρες εμφανίζονται ως εύρος. Αυτό δίνει "21–25 Ιουλίου 2024" αντί για "21 Ιουλίου 2024 – 25 Ιουλίου 2024".
Όχι, ο διαχωριστικός καθορίζεται από το locale και δεν μπορεί να ρυθμιστεί μέσω API. Για προσαρμοσμένο διαχωριστικό (για παράδειγμα, "έως" αντί για "–"), μορφοποιήστε κάθε ημερομηνία με ξεχωριστό DateFormatter και συνδέστε τις συμβολοσειρές χειροκίνητα.
DateIntervalFormatter μορφοποιεί ένα εύρος ημερομηνιών (δύο ημερομηνίες) ως ένα σύνολο με ομαδοποίηση στοιχείων. DateFormatter μορφοποιεί μία ημερομηνία. Για εύρη χρησιμοποιείτε πάντα DateIntervalFormatter — αυτό εξασφαλίζει σωστή τοπικοποίηση του διαχωριστικού.
Αυτόματα — το DateIntervalFormatter ανιχνεύει ότι τα έτη είναι διαφορετικά και εμφανίζει πλήρεις ημερομηνίες και για τα δύο άκρα: "25 Δεκεμβρίου 2024 – 5 Ιανουαρίου 2025". Δεν απαιτούνται πρόσθετες ρυθμίσεις, αρκεί να ορίσετε το dateStyle.
Περίληψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης