Date — adalah struktur Foundation yang mewakili momen waktu tertentu terlepas dari kalender dan zona waktu. Tipe ini menyimpan jumlah detik yang telah berlalu sejak tanggal referensi 1 Januari 2001 (reference date) dan menyediakan operasi dasar perbandingan dan perhitungan interval waktu. Menurut Apple Developer Documentation (2025), Date digunakan di semua framework Apple: dari UIKit dan SwiftUI hingga CloudKit dan Core Data. Memahami cara kerja Date wajib bagi setiap pengembang iOS, karena tanpa itu tidak mungkin mengelola waktu dalam aplikasi.
Poin Utama
Date — adalah tipe nilai dari framework Foundation yang mencatat satu momen waktu absolut. Berbeda dengan representasi kalender (tahun, bulan, hari), Date tidak tergantung pada zona waktu dan sistem kalender — ini adalah nilai numerik murni dari stempel waktu.
Representasi internal Date adalah TimeInterval (alias untuk Double) yang menyimpan jumlah detik relatif terhadap tanggal referensi — 1 Januari 2001 00:00:00 UTC. Apple memilih tanggal ini alih-alih Unix epoch (1970) untuk kompatibilitas dengan sistem NeXTSTEP lama yang menjadi dasar iOS dan macOS.
Date digunakan sebagai tipe waktu standar di semua API Apple: UIDatePicker, DatePicker, UserDefaults, Codable, Core Data, CloudKit. Tanpa Date, tidak mungkin bekerja dengan jadwal, timer, acara kalender, serialisasi data, dan operasi apa pun yang terkait dengan waktu.
Date berbeda dari tipe kalender karena mewakili stempel waktu fisik, bukan nilai yang dapat dibaca manusia. Date yang sama dapat sesuai dengan tanggal kalender yang berbeda di zona waktu yang berbeda. Untuk mendapatkan komponen (tahun, bulan, hari), Date diubah melalui Calendar dan DateComponents.
Date juga berbeda dari DispatchTime, yang digunakan untuk pengiriman tugas di Grand Central Dispatch. DispatchTime relatif terhadap momen startup sistem, sementara Date adalah stempel absolut yang dapat disimpan, ditransmisikan, dan dipulihkan.
Date() — adalah cara paling sederhana untuk membuat objek dengan momen waktu saat ini. Initialisator tanpa argumen mengembalikan waktu pemanggilan yang tepat. Untuk membuat tanggal di masa lalu atau masa depan, gunakan TimeInterval dan metode addingTimeInterval, atau inisialisasi dari Date yang sudah ada.
Untuk membuat tanggal arbitrer dari komponen, gunakan pasangan Calendar dan DateComponents. Calendar mengubah komponen yang dapat dibaca manusia (tahun, bulan, hari, jam, menit) menjadi Date. Juga dapat menginisialisasi Date melalui ISO8601DateFormatter dari string dalam format ISO 8601 atau melalui DateFormatter dari representasi string arbitrer.
Date.distantPast dan Date.distantFuture — dua properti statis yang mewakili momen yang sangat jauh di masa lalu dan masa depan. Mereka digunakan sebagai nilai batas saat memfilter dan mengurutkan tanggal dalam algoritma.
import Foundation
// Membuat Date dengan waktu saat ini
let now = Date()
print("Current time: \(now)")
// Tanggal dalam 1 jam (3600 detik)
let inOneHour = now.addingTimeInterval(3600)
// Tanggal dari komponen
var components = DateComponents()
components.year = 2025
components.month = 12
components.day = 25
let christmas = Calendar.current.date(from: components)!
Dalam contoh ditunjukkan tiga cara membuat Date: waktu saat ini, menambahkan interval, dan membuat melalui DateComponents. Ketiga pendekatan mengembalikan nilai bertipe Date dengan presisi milidetik. Calendar.current menggunakan kalender sistem pengguna — pada perangkat Apple biasanya kalender Gregorian.
TimeInterval — adalah alias untuk Double yang mewakili jumlah detik antara dua momen waktu. Presisi TimeInterval mencapai pecahan milidetik, yang cukup untuk sebagian besar tugas aplikasi. Nilai TimeInterval negatif menunjukkan masa lalu relatif terhadap titik referensi.
Date mendukung semua operator perbandingan standar: ==, <, >, <=, >=. Swift secara otomatis membandingkan TimeInterval internal nilai. Metode compare mengembalikan ComparisonResult dengan varian .orderedSame, .orderedAscending, .orderedDescending untuk perbandingan yang lebih eksplisit.
Date.distance(to:) — metode yang mengembalikan TimeInterval hingga tanggal yang ditentukan. Jika tanggal target di masa lalu, hasilnya negatif. advanced(by:) membuat tanggal baru dengan menambahkan TimeInterval yang ditentukan ke tanggal saat ini. Metode ini mengimplementasikan protokol Strideable, memungkinkan penggunaan Date dalam rentang Range dan ClosedRange.
let start = Date()
let end = start.addingTimeInterval(86400)
// Perbandingan melalui operator
if start < end {
print("start is earlier")
}
// TimeInterval antara dua tanggal
let interval: TimeInterval = end.timeIntervalSince(start)
print("Seconds: \(Int(interval / 60)) minutes")
// Using Date in range
let range = start...end
let mid = start.addingTimeInterval(43200)
if range.contains(mid) {
print("mid is between start and end")
}
TimeInterval sama dengan 86400 sesuai dengan satu hari. Untuk interval yang lebih kompleks — minggu, bulan, tahun — gunakan Calendar dan DateComponents, karena unit-unit ini memiliki panjang variabel (tahun kabisat, perubahan waktu musim panas). TimeInterval hanya berlaku untuk interval tetap dalam detik.
Calendar — adalah jembatan antara Date dan komponen yang dapat dibaca manusia. Calendar mengubah Date menjadi DateComponents (tahun, bulan, hari, jam, menit, detik) dengan mempertimbangkan zona waktu dan lokal. Tanpa Calendar, tidak mungkin mengekstrak tahun atau bulan dari Date — Date tidak mengandung informasi ini karena sifat absolutnya.
Metode Calendar.component mengekstrak satu komponen dari Date: tahun, bulan, hari, jam, menit, detik, weekday, quarter. Metode Calendar.dateComponents mengekstrak satu set komponen dalam satu panggilan — ini lebih efisien daripada memanggil component untuk setiap bidang secara terpisah.
Calendar.isDateInToday, isDateInTomorrow, isDateInYesterday — metode yang nyaman untuk memeriksa tanggal relatif. Calendar.dateInterval mengembalikan awal dan akhir periode yang ditentukan (hari, minggu, bulan, tahun). Calendar.compare membandingkan tanggal dengan presisi komponen yang ditentukan — misalnya, tahun tanpa memperhitungkan bulan dan hari.
let calendar = Calendar.current
// Mengekstrak komponen
let year = calendar.component(.year, from: Date())
let month = calendar.component(.month, from: Date())
// Check relative date
if calendar.isDateInToday(someDate) {
print("Today!")
}
// Awal dan akhir hari
let dayInterval = calendar.dateInterval(of: .day, for: Date())!
print("Day start: \(dayInterval.start)")
print("Day end: \(dayInterval.end)")
Calendar.current menggunakan pengaturan sistem pengguna — kalender, zona waktu, dan lokal. Untuk pengujian atau perhitungan spesifik, Anda dapat membuat Calendar dengan parameter konkret melalui Calendar(identifier: .gregorian) dan mengatur TimeZone yang diinginkan melalui properti timeZone.
DateFormatter — komponen wajib jika Date perlu ditampilkan kepada pengguna. DateFormatter mengubah Date menjadi string sesuai format dan lokal yang ditentukan. Konversi langsung Date ke string melalui String(describing:) mengembalikan representasi teknis dengan reference date dan TimeInterval — tidak dimaksudkan untuk pengguna.
Pendekatan dasar adalah menggunakan gaya yang telah ditentukan sebelumnya dateStyle dan timeStyle. iOS mendukung empat gaya: .short, .medium, .long, .full. Kombinasi gaya tanggal dan waktu memungkinkan penyesuaian tampilan yang fleksibel. DateFormatter secara otomatis menerapkan lokalisasi: untuk lokal Indonesia, tanggal akan ditampilkan dalam format \"21 Juli 2026\".
ISO8601DateFormatter — formatter khusus untuk ISO 8601, format paling umum untuk API dan pertukaran data. Formatter ini bekerja lebih cepat daripada DateFormatter dan tidak tergantung pada lokal, menjadikannya pilihan utama untuk serialisasi tanggal dalam JSON.
// Gaya yang telah ditentukan
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
let userString = formatter.string(from: Date())
// ISO 8601 untuk API
let isoFormatter = ISO8601DateFormatter()
let apiString = isoFormatter.string(from: Date())
// Parsing dari string
let parsed = isoFormatter.date(from: "2026-07-21T10:30:00Z")!
Saat bekerja dengan DateFormatter, penting untuk mengingat kinerja: membuat formatter baru adalah operasi yang mahal. Disarankan untuk menyimpan cache formatter atau membuatnya sekali dan menggunakannya kembali. Dalam properti formatter, Anda dapat mengatur timeZone — secara default zona waktu sistem digunakan, tetapi untuk tanggal server sering diperlukan TimeZone(identifier: \"UTC\").
Mari kita lihat skenario umum bekerja dengan Date di aplikasi iOS. Skenario pertama — menghitung usia pengguna dari tanggal lahir. Kedua — timer hitung mundur hingga suatu acara. Ketiga — pengelompokan catatan berdasarkan tanggal untuk ditampilkan sebagai bagian tabel.
Calendar.dateComponents dengan bendera [.year] menghitung selisih antara dua tanggal. Mengatur zona waktu yang benar sangat penting — jika Anda tidak menentukan timeZone di Calendar, hasilnya mungkin berbeda satu hari karena melewati tengah malam di zona waktu lain.
func calculateAge(from birthDate: Date) -> Int {
let calendar = Calendar.current
let now = Date()
let components = calendar.dateComponents(
[.year], from: birthDate, to: now
)
return components.year ?? 0
}
Timer hitung mundur diimplementasikan melalui TimeInterval. Kami menghitung selisih antara tanggal target dan tanggal saat ini, mendapatkan sisa dalam detik, dan mengonversinya menjadi hari, jam, menit. Untuk pembaruan rutin, digunakan Timer dengan interval 1 detik. ObservableObject dengan properti @Published memungkinkan SwiftUI memperbarui antarmuka secara otomatis.
Pengelompokan berdasarkan tanggal diimplementasikan melalui kamus dengan kunci Date. Calendar.dateInterval(of: .day, for:) menormalkan tanggal ke awal hari, memungkinkan pengelompokan catatan yang termasuk dalam hari yang sama. Pendekatan yang sama berlaku untuk minggu, bulan, dan tahun — cukup ubah komponen di dateInterval menjadi .weekOfYear atau .month.
| Skenario | API Kunci | Fitur |
|---|---|---|
| Menghitung usia | Calendar.dateComponents | Perhitungkan timeZone |
| Hitung mundur | Date.timeIntervalSince | Timer+Combine |
| Pengelompokan tanggal | Calendar.dateInterval | Normalisasi hingga hari |
| Serialisasi JSON | ISO8601DateFormatter | Locale tidak berpengaruh |
Pertanyaan yang Sering Diajukan
Date — adalah representasi internal waktu tanpa keterkaitan dengan kalender dan lokal. String adalah tampilan terformat yang tergantung pada pengaturan pengguna. Date dapat dibandingkan, diserialisasi, dan diproses secara matematis dengan akurasi seratus persen, sedangkan representasi string selalu memerlukan parsing melalui formatter.
Date — adalah stempel waktu absolut (jumlah detik dari reference date) yang tidak tergantung pada zona waktu. Zona waktu adalah konteks tampilan. Date yang sama di UTC dan di Jakarta mewakili momen fisik yang sama, tetapi ditampilkan sebagai waktu kalender yang berbeda.
Date didukung langsung oleh Core Data sebagai tipe atribut. Core Data secara otomatis menserialisasi Date di penyimpanan. Untuk kueri dengan pemfilteran berdasarkan tanggal, gunakan NSPredicate dengan operator perbandingan — Core Data memproses timezone dengan benar di tingkat SQLite.
CFAbsoluteTime — adalah tipe Core Foundation yang menggunakan tanggal referensi yang sama (1 Januari 2001). Date dan CFAbsoluteTime dapat dipertukarkan melalui konversi langsung. Date(timeIntervalSinceReferenceDate:) menerima CFAbsoluteTime, dan Date.timeIntervalSinceReferenceDate mengembalikan CFAbsoluteTime.
Date memiliki presisi hingga milidetik, tetapi tidak menjamin presisi nanodetik karena keterbatasan perangkat keras iOS/macOS. Untuk pengukuran presisi tinggi, gunakan mach_absolute_time atau ContinuousClock dari Swift 5.7+, yang bekerja pada penghitung siklus prosesor perangkat keras.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga