DateFormatter: Temel kavramlar, tarih biçimlendirme ve yerelleştirme

Yazar: IT Sectr Yayınlanma: 2026-07-12 Okuma süresi: 7 dk

DateFormatter, Date nesneleri ile bunların dize temsilleri arasında çift yönlü dönüşüm için tasarlanmış bir Foundation sınıfıdır. Sınıf, kullanıcının yerel ayarını, saat dilimini ve takvimini dikkate alarak dünyanın herhangi bir bölgesinde tarihlerin doğru görüntülenmesini sağlar. Apple Developer Documentation'a (2025) göre DateFormatter, dört önceden ayarlanmış tarih ve saat stilinin yanı sıra bir şablon dizesi aracılığıyla tamamen özel biçimleri destekler. DateFormatter olmadan, uluslararasılaştırılmış bir uygulamada kullanıcıya bir tarihi doğru şekilde görüntülemek imkansızdır.

Önemli Çıkarımlar

  • DateFormatter — yerel ayar ve saat dilimi desteğiyle Date'i dizeye ve geri dönüştürmek için bir sınıf.
  • dateStyle ve timeStyle — hızlı biçimlendirme için önceden ayarlanmış stiller (.short, .medium, .long, .full).
  • dateFormat — Unicode LDML sembolleri aracılığıyla belirtilen özel biçim için bir şablon dizesi.
  • Locale ve TimeZone — bölgesel görüntülemeyi ve saat dilimini belirleyen biçimlendirici özellikleri.
  • ISO8601DateFormatter — API'de serileştirme sırasında ISO 8601 biçimi için daha hızlı bir alternatif.

DateFormatter Nedir?

DateFormatter, Foundation framework'ünün Date ve dize arasında çift yönlü dönüşüm uygulayan bir sınıfıdır. İlk olarak OpenStep'te NSDateFormatter olarak ortaya çıkmış ve o zamandan beri tüm Apple platformlarında tarih biçimlendirme için birincil araç olarak kalmıştır. Sınıf, Formatter'dan miras alır ve yerelleştirilmiş tarih görüntüleme için kullanışlı bir API sağlar.

DateFormatter, Unicode LDML kalıplarına dayalı olarak çalışır — ICU'da (International Components for Unicode) kullanılanlarla aynı. Kalıp, dateFormat özelliği aracılığıyla ayarlanır ve y, M, d, H, m, s sembolleri yıl, ay, gün, saat, dakika, saniyeye karşılık gelir. Bir sembolün tekrarı biçimi belirler: “y” — iki basamaklı yıl, “yyyy” — dört basamaklı yıl.

DateFormatter oluşturmak pahalı bir işlemdir, çünkü başlatma sırasında yerel ayar ve takvim verileri yüklenir. Apple, her biçimlendirme türü için bir kez biçimlendirici oluşturmayı ve yeniden kullanmayı önerir. SwiftUI ve UIKit'te, biçimlendiriciler genellikle statik özelliklerde önbelleğe alınır veya ilk erişimde tembelce oluşturulur.

iOS SDK'da DateFormatter

DateFormatter, birçok iOS sistem bileşeninde kullanılır. UIDatePicker, countDownTimer modunda tarihleri görüntülemek için dahili olarak DateFormatter'ı kullanır. Bir biçimlendiriciye sahip TextField, kullanıcı tarafından girilen tarihleri otomatik olarak doğrulayabilir. Core Data, Date türündeki nitelikleri destekler, ancak bunların dize temsili her zaman DateFormatter aracılığıyla gerçekleştirilir.

İş Parçacığı Güvenliği — DateFormatter iş parçacığı güvenli değildir. Farklı iş parçacıklarından biçimlendirici özelliklerini değiştirmek tanımsız davranışa yol açar. Çok iş parçacıklı kullanım için, her iş parçacığı için ayrı biçimlendirici örnekleri oluşturun veya NSLock veya seri kuyruk aracılığıyla senkronizasyon kullanın.

DateFormatter Biçimlendirme Stilleri

dateStyle ve timeStyle, tarih görüntülemeyi yapılandırmanın en basit yollarıdır. Her stilin dört çeşidi vardır: .short, .medium, .long, .full. dateStyle ve timeStyle'ın kombinasyonu, tarih ve saat biçiminin bağımsız olarak yapılandırılmasına olanak tanır ve .none özelliği ilgili kısmı devre dışı bırakır.

ABD yerel ayarı için .short, tarihi “7/21/26” olarak biçimlendirir ve Rus yerel ayarı için “21.07.2026” olarak. Rus yerel ayarı için .long stili “21 Temmuz 2026” çıktısını verir ve .full, haftanın günüyle birlikte “Salı, 21 Temmuz 2026” çıktısını verir. Dört stilin tümü, bileşen sırası ve ayırıcılar dahil olmak üzere otomatik olarak bölgesel standartlara uyum sağlar.

iOS 15+ içindeki SFDateFormatter, RelativeDateFormatter ve DateIntervalFormatter aracılığıyla alternatif bir yaklaşım sunar. RelativeDateFormatter, anlık bağlam için “bugün”, “dün”, “3 gün içinde” çıktısını verir. DateIntervalFormatter, tarih aralıklarını görüntüler: “21–25 Temmuz 2026” — rezervasyonlar ve planlama için.

StilÖrnek (ru_RU)Örnek (en_US)
.short21.07.20267/21/26
.medium21 Tem 2026Jul 21, 2026
.long21 Temmuz 2026July 21, 2026
.fullSalı, 21 Temmuz 2026Tuesday, July 21, 2026

Stilleri birleştirirken, DateFormatter otomatik olarak ayırıcıyı seçer: .short.date + .short.time için sonuç “21.07.2026, 14:30” olabilir. .full.date + .full.time için — “Salı, 21 Temmuz 2026, 14:30:00 MSK”. Ayırıcı, geliştirici tarafından değil, yerel ayar tarafından yönetilir — bu, kullanıcının bölgesel beklentilerine uygunluğu garanti eder.

dateFormat ile Özel Biçimler

dateFormat, Unicode LDML belirtim sembollerini kullanarak isteğe bağlı bir biçimlendirme kalıbı ayarlamaya olanak tanır. Bu, görüntüleme üzerinde tam kontrol sağlar: yalnızca yıl ve ayı veya tarihsiz haftanın gününü veya saniyesiz saati görüntüleyebilirsiniz. Özel biçim, belirli tasarım gereksinimleri için vazgeçilmezdir.

Ana semboller — yyyy (yıl: 2026), MM (ay: 07), dd (gün: 21), HH (saat: 14), mm (dakika: 30), ss (saniye: 00). Tam ay adı için MMMM (Temmuz), kısaltılmış için — MMM (Tem) kullanın. Haftanın günü — EEEE (Salı), kısaltılmış — E (Sal).

dateFormat kullanırken biçimlendiricinin yerel ayarını ayarlamak önemlidir. Yerel ayar ayarlanmazsa, biçimlendirici sistem yerel ayarını kullanır, bu bir API'de sabit bir biçim için istenmeyebilir. Apple, özellikle sunucu yanıtlarından tarihleri ayrıştırırken, sabit bir bölgeler arası biçim için locale = Locale(identifier: “en_US_POSIX”) ayarlamayı önerir.

swift
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "ru_RU")
formatter.dateFormat = "d MMMM yyyy"
let customString = formatter.string(from: Date())
// "21 July 2026"

// Özel bir dizeyi ayrıştırma
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let date = formatter.date(from: "2026-07-21 14:30:00")!

dateFormat'taki bir hata, uygulama çökmelerinin yaygın nedenlerinden biridir. Biçim dizeyle eşleşmezse, date(from:) yöntemi nil döndürür. Güvenli isteğe bağlı açma için guard let veya ?? kullanın. Biçimi doğrulamak için, desteklenen tüm dillerde test edin — bazı LDML sembolleri farklı yerel ayarlarda farklı çalışır.

Yerelleştirme ve TimeZone

Locale, ay adlarının, haftanın günü adlarının ve ayırıcıların nasıl görüntüleneceğini belirler. DateFormatter varsayılan olarak Locale.current kullanır, ancak bazı senaryolarda belirli bir yerel ayar belirtilmesi gerekir: günlüklerde sabit bir biçim için en_US_POSIX kullanın, sunucu tarihleri için — sunucuyla eşleşen yerel ayarı kullanın.

TimeZone özelliği, görüntüleme için saat dilimini belirler. Varsayılan olarak sistem saat dilimi kullanılır, ancak uluslararası kitleye sahip uygulamalar için genellikle tarihlerin kullanıcının saat diliminde veya UTC'de görüntülenmesi gerekir. TimeZone'u değiştirmek yalnızca görüntülemeyi etkiler — Date değeri değişmez.

Önemli bir özellik: DateFormatter bir dizeyi ayrıştırmak için kullanılırsa ve dize bir saat dilimi göstergesi içeriyorsa (örneğin, UTC için Z ile “2026-07-21T14:30:00Z”), timeZone özelliği yok sayılır — biçimlendirici dizedeki saat dilimini kullanır. Dizede saat dilimi yoksa, biçimlendiricinin timeZone'u uygulanır.

swift
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "ru_RU")
formatter.timeZone = TimeZone(identifier: "Europe/Moscow")
formatter.dateStyle = .long
formatter.timeStyle = .short

let moscowTime = formatter.string(from: Date())
// "21 July 2026, 14:30"

// Dizede saat dilimi olmadan ayrıştırma
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd HH:mm"
let utcDate = formatter.date(from: "2026-07-21 10:30")!

AutoupdatingCurrentLocale — kullanıcının sistem ayarları değiştiğinde otomatik olarak güncellenen özel bir yerel ayar türüdür. DateFormatter varsayılan olarak bunu destekler. Uygulama arka planda çalışırken kullanıcı sistem dilini değiştirirse, değişiklikten önce oluşturulan bir biçimlendirici eski yerel ayarı kullanmaya devam eder — güncellemek için yeni bir örnek oluşturulması gerekir.

ISO8601DateFormatter ve Alternatifler

ISO8601DateFormatter, ISO 8601 biçimindeki tarihlerle çalışmak için özel bir biçimlendiricidir. Bu biçim, REST API'leri, JSON ve veri alışverişi için fiili standarttır. ISO8601DateFormatter, yerel ayara bağlı olmadığı ve sabit bir ayrıştırma dil bilgisi kullandığı için DateFormatter'dan önemli ölçüde daha hızlı çalışır.

Ana biçimlendirici seçenekleri — .withInternetDateTime (2026-07-21T14:30:00Z), .withFractionalSeconds (milisaniye ekler), .withTimeZone (saat dilimi farkını içerir). Seçenekleri birleştirerek herhangi bir ISO 8601 çeşidini elde edebilirsiniz: milisaniyeli, saat dilimli, yalnızca tarihli.

JSONEncoder.DateEncodingStrategy, tüm Codable modelleri için küresel olarak tarih kodlamasını yapılandırmaya olanak tanır. Seçenekler — .iso8601 (ISO8601DateFormatter kullanır), .formatted(DateFormatter), .millisecondsSince1970, .secondsSince1970. Strateji seçimi, tüm serileştirme yaşam döngüsünü etkiler ve tüm API uç noktalarında tutarlı olmalıdır.

swift
// ISO8601DateFormatter
let isoFormatter = ISO8601DateFormatter()
isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let isoString = isoFormatter.string(from: Date())
// "2026-07-21T14:30:00.000Z"

// ISO8601 ile JSONEncoder
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601

// Alternatif: Özel biçimlendirici ile JSONEncoder
let customEncoder = JSONEncoder()
customEncoder.dateEncodingStrategy = .formatted(myFormatter)

DateFormatter vs ISO8601DateFormatter — API'de tarihleri serileştirmek ve ayrıştırmak için ISO8601DateFormatter'ı seçin, çünkü DateFormatter'dan 5-10 kat daha hızlıdır ve yerelleştirme hatalarına eğilimli değildir. Kullanıcının ana dilinde ay ve gün adlarıyla yerelleştirilmiş görüntülemenin gerektiği kullanıcı arabirimi için DateFormatter'ı kullanın.

Tarih Biçimlendirme Örnekleri

Bir iOS uygulamasında DateFormatter kullanımının gerçek dünya senaryolarına bakalım: haber akışında tarih görüntüleme, doğum tarihi girme ve farklı saat dilimlerinde tarihler içeren bir raporu dışa aktarma.

Bir listede haber tarihini görüntüleme

RelativeDateFormatter, haber akışları için idealdir. Yeni haberler için “şimdi”, “5 dakika önce”, “dün” görüntüler ve eskileri için tam tarihe geçer. Geçiş eşiği takvim aracılığıyla yapılandırılır: haberler için 24 saatlik bir eşik kullanın, mesajlaşma uygulamaları için — bir hafta.

swift
func formatRelativeDate(_ date: Date) -> String {
    let relative = RelativeDateFormatter()
    relative.unitsStyle = .full

    let formatter = DateFormatter()
    formatter.dateStyle = .medium
    formatter.timeStyle = .short

    let daysDiff = Calendar.current.dateComponents(
        [.day], from: date, to: Date()
    ).day ?? 0

    return daysDiff < 1
        ? relative.localizedString(for: date, relativeTo: Date())
        : formatter.string(from: date)
}

Doğum tarihi girme — başka bir yaygın senaryo. DateFormatter, belirli bir dateFormat “dd.MM.yyyy” ve locale “ru_RU” ile yapılandırılır. Girilen dizeyi ayrıştırırken olası hataları ele almak önemlidir: biçimlendirici geçersiz bir dize için nil döndürür. Başarılı ayrıştırmadan sonra, tarihin kabul edilebilir bir aralıkta olduğu kontrol edilir — 1900'den önce değil, bugünden sonra değil.

Tarihler içeren bir raporu dışa aktarma, kullanıcının yerel ayarından bağımsız sabit bir biçim gerektirir. locale en_US_POSIX ve saat dilimi UTC ile dateFormat “yyyy-MM-dd HH:mm:ss” kullanın. Bu yaklaşım, dosyanın sistemin bölgesel ayarlarından bağımsız olarak herhangi bir ülkede do\uğru şekilde açılmasını garanti eder.

SenaryoBiçimlendiriciAnahtar Ayar
Haber akışıRelativeDateFormatterunitsStyle = .full
Tarih girişiDateFormatterdateFormat + yedek
API serileştirmeISO8601DateFormatterwithInternetDateTime
Rapor dışa aktarmaDateFormatteren_US_POSIX + UTC

Sıkça Sorulan Sorular

DateFormatter neden geçerli bir dize için nil döndürüyor?

En yaygın neden — dateFormat ile dize biçimi arasındaki uyuşmazlık. Örne\uğin, “dd.MM.yyyy” biçimi “2026-07-21” dizesini ayrıştırmaz. İkinci neden — yerel ayar uyuşmazlığı: “July 21, 2026” dizesi ru_RU yerel ayarıyla ayrıştırılmaz. Üçüncüsü — LDML sembollerinde yazım hatası: yyyy kullanın, YYYY değil (farklı anlam).

Her ça\uğrı için yeni bir DateFormatter oluşturmalı mıyım?

Hayır. DateFormatter ağır bir nesnedir, başlatılması yerel ayar verilerinin yüklenmesini içerir. Her biçimlendirme türü için bir örnek oluşturun ve yeniden kullanın. Çok iş parçacıklı bir ortamda, iş parçacığı yerel depolamasını veya senkronizasyon için seri kuyruklu bir biçimlendirici havuzu kullanın.

DateFormatter, RelativeDateFormatter'dan nasıl farklıdır?

DateFormatter mutlak bir tarih görüntüler (21 Temmuz 2026), RelativeDateFormatter ise göreli bir tarih görüntüler (bugün, dün, 3 gün içinde). RelativeDateFormatter iOS 15+ ile tanıtıldı ve aynı LDML şablonunu kullanır ancak otomatik olarak göreli görüntülemeyi seçer.

API'den saat dilimi olmayan tarihler nasıl ele alınır?

Biçimlendiricinin timeZone'unu ayrıştırmadan önce UTC olarak ayarlayın. Sunucu, saat dilimi belirtmeden yerel saatte bir tarih döndürürse, API belirtimini kontrol edin — büyük olasılıkla UTC kastedilmiştir. Sonunda Z olan ISO 8601 için timeZone gerekmez — biçimlendirici dizeden farkı ayrıştırır.

DateFormatter nasıl iş parçacığı güvenli hale getirilir?

Senkronizasyon olmadan farklı iş parçacıklarından tek bir örnek kullanmayın. Her iş parçacığında yeni bir örnek oluşturun veya depolama için Thread.current.threadDictionary kullanın. Bir alternatif, string(from:) ve date(from:) süresince kilitlemeli NSLock'tur.

Özet

  • DateFormatter — yerel ayar, saat dilimi ve takvim desteğiyle Date'i dizeye ve geri dönüştürmek için bir Foundation sınıfı.
  • Önceden ayarlanmış stiller dateStyle ve timeStyle, .short, .medium, .long, .full çeşitleriyle çoğu kullanıcı arabirimi senaryosunu kapsar.
  • Özel dateFormat, LDML sembolleri aracılığıyla biçim üzerinde tam kontrol sağlar ancak yerelleştirme konusunda dikkatli olunmasını gerektirir.
  • Locale ve TimeZone — doğru görüntüleme için gerekli özellikler: kullanıcı arabirimi için — sistem yerel ayarı, API için — en_US_POSIX ve UTC.
  • ISO8601DateFormatter — hız ve kararlılık nedeniyle API'de tarih serileştirme için tercih edilen seçim.
  • DateFormatter iş parçacığı güvenli değildir — her iş parçacığı için ayrı örnekler kullanın veya erişimi senkronize edin.
  • RelativeDateFormatter (iOS 15+) — haber akışlarında ve mesajlaşma uygulamalarında göreli tarihleri görüntülemek için en uygun çözüm.

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.

Projeyi tartış

Ayrıca okuyun