DateIntervalFormatter, iOS ve macOS'ta tarih aralıklarını yerelleştirilmiş dizelere biçimlendirmek için tasarlanmış bir Foundation sınıfıdır: “21–25 Temmuz 2024”, “21–25 Temmuz 2024 arası” veya “Jul 21–25, 2024”. Apple Developer Documentation, 2024'e göre, DateIntervalFormatter hangi tarih bileşenlerinin tekrarlanacağını otomatik olarak belirler (aralık bir ay içindeyse, ay bir kez gösterilir) ve ayırıcıları ile kelime sırasını yerelleştirir. İki biçimlendirilmiş tarihi manuel olarak birleştirmenin aksine, bu sınıf dilin dilbilgisi kurallarını dikkate alır. Sınıf, iOS 8 ve macOS 10.10'dan itibaren kullanılabilir.
Ana Noktalar
DateIntervalFormatter, Foundation'da Formatter'ın bir alt sınıfıdır ve bir DateInterval nesnesi (iki tarih arasındaki aralık) alır ve bu aralığı tanımlayan yerelleştirilmiş bir dize döndürür. Örneğin, 21–25 Temmuz 2024 aralığı için sonuç, tr_TR için “21–25 Temmuz 2024” olacaktır. Sınıf, yinelenen öğeleri akıllıca gruplar: her iki tarih aynı aydaysa, ay adı bir kez gösterilir.
DateIntervalFormatter'ın temel değeri, aralık dilbilgisinin otomatik olarak işlenmesidir. Manuel biçimlendirme sırasında, bir geliştiricinin başlangıç/bitiş ayını/yılını karşılaştırması, bir ayırıcı seçmesi (çizgi, “arası”, “bis”) ve çekim eklerini yönetmesi gerekir. DateIntervalFormatter, CLDR (Common Locale Data Repository) verilerine dayanarak bunu otomatik olarak yapar ve uluslararası uygulamalardaki hataları azaltır, özellikle karmaşık dilbilgisine sahip diller için.
Unicode CLDR v44 (2024)'e göre, tarih aralığı biçimlendirme kuralları diller arasında önemli ölçüde farklılık gösterir. Almanca “bis” (21.–25. Juli 2024), Fransızca “au” (du 21 au 25 juillet 2024), Japonca kısa çizgi (2024 Jul 21–25) kullanır. DateIntervalFormatter, geliştirici tarafında ek kod olmadan tüm bu varyasyonları kapsar.
Çalışma prensibi DateIntervalFormatter, bir aralık oluşturan iki tarihi analiz etmeye ve yerel ayarları dikkate alarak en uygun dize temsilini seçmeye dayanır. Sınıf, tarih bileşenlerini (yıl, ay, gün) karşılaştırır ve gruplama kararları alır: yıl aynıysa bir kez gösterilir; ay aynıysa bir kez gösterilir; günler farklıysa, bir gün aralığı gösterilir.
| Aralık | tr_TR |
|---|---|
| Bir gün | 21 Temmuz 2024 |
| Ay içinde | 21–25 Temmuz 2024 |
| Farklı aylar | 21 Temmuz – 5 Ağustos 2024 |
| Farklı yıllar | 25 Aralık 2024 – 5 Ocak 2025 |
| Saatli | 21 Temmuz 2024, 14:30–16:45 |
Gruplama mantığı CLDR şablonlarına dayanarak uygulanır. Biçimlendirici, her tarih bileşeninin (Calendar.Component: year, month, day) eşitliğini büyükten küçüğe sırayla kontrol eder. Bir bileşen farklılaştığında, daha küçük tüm bileşenler her iki tarih için de gösterilir. Örneğin, 21–25 Temmuz için: yıl eşleşir, ay eşleşir, gün farklıdır → ay bir kez gösterilir, günler her tarih için gösterilir.
Önemli not: DateIntervalFormatter, API aracılığıyla ayırıcının özelleştirilmesini desteklemez. Ayırıcı, yerel ayarlar tarafından belirlenir ve geçersiz kılınamaz. Standart olmayan bir ayırıcı gerekiyorsa (örneğin, “arası” yerine “arası”), DateFormatter kullanarak her tarihi manuel olarak biçimlendirmeniz ve dizeleri özel bir ayırıcıyla birleştirmeniz gerekir.
DateIntervalFormatter iki stil seti sağlar: dateStyle ve timeStyle — aralığın her iki ucu için. Bu stiller DateFormatter'a benzer şekilde çalışır: .none bileşeni gizler, .short kısa bir biçim verir (21.07.2024), .medium (21 Tem 2024), .long (21 Temmuz 2024), .full (21 Temmuz 2024 Pazar). dateStyle ve timeStyle'ı birleştirerek farklı detay seviyeleri elde edilebilir.
Önemli: dateStyle ve timeStyle, aralığın her iki ucuna eşit şekilde uygulanır. Başlangıç ve bitiş için farklı stiller ayarlayamazsınız (örneğin, başlangıç için .medium ve bitiş için .short). Farklı stiller gerekiyorsa, her tarihi ayrı bir DateFormatter ile biçimlendirmeli ve sonuçları birleştirmelisiniz.
import Foundation
let formatter = DateIntervalFormatter()
// Farklı stil kombinasyonları
let startDate = Date()
let endDate = Date().addingTimeInterval(345600) // +4 gün
let interval = DateInterval(start: startDate, end: endDate)
// Yalnızca tarih, orta biçim
formatter.dateStyle = .medium
formatter.timeStyle = .none
print("Yalnızca tarih: \(formatter.string(from: interval))")
// Saatli kısa biçim
formatter.dateStyle = .short
formatter.timeStyle = .short
print("Saatli kısa: \(formatter.string(from: interval))")
// Tam biçim
formatter.dateStyle = .full
formatter.timeStyle = .none
print("Tam tarih: \(formatter.string(from: interval))")
Temel kullanım DateIntervalFormatter, bir örnek oluşturma, stilleri ayarlama ve string(from:) çağrısı yapmayı içerir. Yöntem, start ve end özelliklerine sahip bir yapı olan DateInterval'i kabul eder. DateInterval, iki Date değerinden oluşturulabilir veya Duration (iOS 16+) ile başlatılabilir. Biçimlendirmeden sonra sonuç, ek işlem gerektirmeden arayüzde görüntülenmeye hazırdır.
import Foundation
let calendar = Calendar.current
let now = Date()
// Belirli aralık örnekleri
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 ile biçimlendirme (iOS 16+)
if let nextWeek = calendar.date(
byAdding: .day, value: 7, to: now
) {
let weekInterval = DateInterval(start: now, end: nextWeek)
print("Sonraki 7 gün: \(intervalFormatter.string(from: weekInterval))")
}
DateIntervalFormatter ve takvim rezervasyonu: rezervasyon uygulamalarında (oteller, biletler), tarih aralıkları önemli bir arayüz öğesidir. DateIntervalFormatter, yıllar arası aralıkları (örneğin, 28 Aralık – 3 Ocak) doğru şekilde işler ve her tarih için ayı ve yılı ayrı ayrı gruplar. Bu tür senaryolar için dateStyle = .medium ve timeStyle = .none kullanılması önerilir; saat olmadan tarihler için en okunabilir biçimdir.
import Foundation
let formatter = DateIntervalFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .none
// Rezervasyon örnekleri
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("Rezervasyon: \(booking.formattedInterval)")
// Farklı yerel ayarlarla kullanım
let enFormatter = DateIntervalFormatter()
enFormatter.dateStyle = .medium
enFormatter.timeStyle = .none
enFormatter.locale = Locale(identifier: "en_US")
print("İngilizce: \(enFormatter.string(from: interval))")
DateInterval vs DateIntervalFormatter: DateInterval, bir tarih aralığını (başlangıç ve bitiş) temsil eden bir yapıdır. DateIntervalFormatter, bu yapıyı bir dizeye dönüştüren bir biçimlendiricidir. DateInterval ayrıca contains(Date) kontrollerini ve intersection(with:) işlevini destekler; bu, rezervasyon mantığı (tarih çakışması kontrolü) için kullanışlıdır.
DateIntervalFormatter, locale özelliği aracılığıyla çıktıyı yerelleştirir. Varsayılan olarak, cihazın yerel ayarı olan Locale.current kullanılır. Aralıkları başka bir dilde görüntülemek için (örneğin, Türkçe arayüzle İngilizce içerik), locale'i açıkça ayarlayın. DateFormatter'ın aksine, DateIntervalFormatter sunucu tarafı verileri için locale ayarlamayı gerektirmez. Her zaman dahili CLDR tabanlı gruplama mantığını kullanır.
Tarih aralığı biçimlendirmedeki dil farklılıkları, tek tarihlerden önemli ölçüde daha karmaşıktır. Türkçe, “arası” ifadesini kullanır: 21–25 Temmuz arası. İngilizce basit bir çizgi kullanır: Jul 21–25. Fransızca “au” kullanır: du 21 au 25 juillet. DateIntervalFormatter tüm bu varyantları kapsar.
import Foundation
let formatter = DateIntervalFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
let start = Date()
let end = Date().addingTimeInterval(259200) // +3 gün
let interval = DateInterval(start: start, end: end)
// Farklı yerel ayarları gösterme
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))")
}
// Zaman aralıkları için yerelleştirme
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) saati: \(formatter.string(from: timeInterval))")
}
Yerelleştirme özellikleri: Türkçe için DateIntervalFormatter, uzun biçimlerde “arası” ifadesini kullanır. Kısa biçimler için çizgi kullanır. Biçim seçimi bağlama bağlıdır: rezervasyon listesi için .medium, detaylı görünüm için .long veya .full kullanın.
DateIntervalFormatter, diğer Foundation sınıfları tarafından kapsanmayan tarih aralıklarını biçimlendirme alanını doldurur. DateFormatter tek tarihleri, RelativeDateTimeFormatter göreceli tarihleri (önce/içinde), DateComponentsFormatter süreyi (2 saat 30 dakika) biçimlendirir. Bu sınıfların her biri belirli bir görevi çözer ve birbirlerinin yerine kullanılamazlar.
| Sınıf | Amaç | Çıktı örneği |
|---|---|---|
| DateIntervalFormatter | Tarih aralığı | 21–25 Temmuz 2024 |
| DateFormatter | Tek tarih | 21 Temmuz 2024 |
| RelativeDateTimeFormatter | Göreceli zaman | 3 gün önce |
| DateComponentsFormatter | Süre | 2 saat 30 dakika |
| ISO8601DateFormatter | ISO 8601 biçimi | 2024-07-21T14:30:00Z |
DateIntervalFormatter ne zaman kullanılır: arayüzde tarih aralıklarını görüntülemek için — otel rezervasyonu, etkinlikler, tarihe göre filtreleme, işlem geçmişi. Tarihler arasındaki süreyi hesaplamak için DateComponentsFormatter kullanın, DateIntervalFormatter değil, çünkü ikincisi süre görüntülemek için tasarlanmamıştır. DateFormatter yalnızca tek tarihler için kullanılmalıdır, iki biçimlendirilmiş tarihi dize birleştirme yoluyla birleştirmek için kullanılmamalıdır, çünkü bu ayırıcı yerelleştirmesinin kaybına yol açar.
Uç durum: DateIntervalFormatter, açık uçlu aralıkları (bitiş tarihi olmadan) görüntülemeyi desteklemez. Aralığın sonu bilinmiyorsa (örneğin, “21 Temmuz'dan itibaren”), “itibaren” ile DateFormatter kullanın. Ayrıca DateIntervalFormatter, farklı günler için saat belirtilen aralıkları desteklemez. Saat her tarihe ayrı ayrı uygulanır ve kısa aralıklar için gereksiz görünebilir.
Sıkça Sorulan Sorular
DateIntervalFormatter, tarih aralıklarını yerelleştirilmiş dizelere biçimlendiren bir Foundation sınıfıdır. iOS 8'den beri kullanılabilir, yinelenen bileşenleri (ay, yıl) otomatik olarak gruplar ve dil için doğru ayırıcıyı seçer.
Bileşenleri karşılaştırır yıldan güne. Yıl eşleşirse bir kez gösterilir. Ay eşleşirse bir kez gösterilir. Farklı günler bir aralık olarak gösterilir. Bu, “21 Temmuz 2024 – 25 Temmuz 2024” yerine “21–25 Temmuz 2024” verir.
Hayır, ayırıcı yerel ayarlar tarafından belirlenir ve API aracılığıyla özelleştirilemez. Özel bir ayırıcı için (örneğin, “arası” yerine “arası”), her tarihi ayrı bir DateFormatter ile biçimlendirin ve dizeleri manuel olarak birleştirin.
DateIntervalFormatter bir tarih aralığını (iki tarih) bileşen gruplamasıyla tek bir birim olarak biçimlendirir. DateFormatter tek bir tarihi biçimlendirir. Aralıklar için her zaman DateIntervalFormatter kullanın çünkü doğru ayırıcı yerelleştirmesi sağlar.
Otomatik olarak — DateIntervalFormatter yılların farklı olduğunu algılar ve her iki uç için tam tarihleri gösterir: “25 Aralık 2024 – 5 Ocak 2025”. Ek yapılandırma gerekmez, sadece dateStyle'ı ayarlayın.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun