Date — este o structură Foundation care reprezintă un moment specific în timp, independent de calendar și de fusul orar. Tipul stochează numărul de secunde scurse de la data de referință 1 ianuarie 2001 (reference date) și oferă operații de bază de comparare și calcul al intervalelor de timp. Conform Apple Developer Documentation (2025), Date este utilizat în toate framework-urile Apple: de la UIKit și SwiftUI până la CloudKit și Core Data. Înțelegerea modului de funcționare a Date este obligatorie pentru orice dezvoltator iOS, deoarece fără el nu se poate gestiona timpul în aplicație.
Principalele puncte
Date — este un tip-valoare din framework-ul Foundation care înregistrează un singur moment absolut de timp. Spre deosebire de reprezentările calendaristice (an, lună, zi), Date nu depinde de fusul orar și de sistemul de calendar — este o valoare pur numerică a unui marcaj temporal.
Reprezentarea internă a Date este un TimeInterval (alias pentru Double) care stochează numărul de secunde față de data de referință — 1 ianuarie 2001 00:00:00 UTC. Apple a ales această dată în loc de Unix epoch (1970) pentru compatibilitate cu sistemele vechi NeXTSTEP, pe baza cărora au fost construite iOS și macOS.
Date este utilizat ca tip standard de timp în toate API-urile Apple: UIDatePicker, DatePicker, UserDefaults, Codable, Core Data, CloudKit. Fără Date, nu se poate lucra cu programări, cronometre, evenimente de calendar, serializare de date și orice operațiuni legate de timp.
Date se deosebește de tipurile calendaristice prin faptul că reprezintă un marcaj temporal fizic, nu o valoare lizibilă pentru om. Același Date poate corespunde unor date calendaristice diferite în fusuri orare diferite. Pentru obținerea componentelor (an, lună, zi), Date este transformat prin Calendar și DateComponents.
Date diferă, de asemenea, de DispatchTime, care este utilizat pentru expedierea sarcinilor în Grand Central Dispatch. DispatchTime este relativ la momentul pornirii sistemului, în timp ce Date este un marcaj absolut care poate fi salvat, transmis și restaurat.
Date() — este cel mai simplu mod de a crea un obiect cu momentul curent de timp. Inițializatorul fără argumente returnează timpul exact al apelării. Pentru a crea o dată în trecut sau viitor, se utilizează TimeInterval și metoda addingTimeInterval sau inițializarea dintr-un Date existent.
Pentru a crea o dată arbitrară din componente, se utilizează perechea Calendar și DateComponents. Calendar transformă componentele lizibile pentru om (an, lună, zi, oră, minut) în Date. De asemenea, se poate inițializa Date prin ISO8601DateFormatter dintr-un șir în format ISO 8601 sau prin DateFormatter dintr-o reprezentare în șir arbitrară.
Date.distantPast și Date.distantFuture — două proprietăți statice care reprezintă momente infinit de îndepărtate ale trecutului și viitorului. Ele sunt utilizate ca valori limită la filtrarea și sortarea datelor în algoritmi.
import Foundation
// Crearea Date cu timpul curent
let now = Date()
print("Current time: \(now)")
// Data peste 1 oră (3600 de secunde)
let inOneHour = now.addingTimeInterval(3600)
// Data din componente
var components = DateComponents()
components.year = 2025
components.month = 12
components.day = 25
let christmas = Calendar.current.date(from: components)!
În exemplu sunt prezentate trei moduri de a crea Date: timpul curent, adăugarea unui interval și crearea prin DateComponents. Toate cele trei abordări returnează o valoare de tip Date cu precizie de milisecundă. Calendar.current utilizează calendarul de sistem al utilizatorului — pe dispozitivele Apple acesta este de obicei calendarul gregorian.
TimeInterval — este un alias pentru Double care reprezintă numărul de secunde dintre două momente de timp. Precizia TimeInterval atinge fracțiuni de milisecundă, ceea ce este suficient pentru majoritatea sarcinilor aplicative. O valoare negativă TimeInterval indică trecutul față de punctul de referință.
Date suportă toți operatorii standard de comparare: ==, <, >, <=, >=. Swift compară automat TimeInterval intern al valorilor. Metoda compare returnează un ComparisonResult cu variantele .orderedSame, .orderedAscending, .orderedDescending pentru o comparare mai explicită.
Date.distance(to:) — metodă care returnează TimeInterval până la data specificată. Dacă data țintă este în trecut, rezultatul este negativ. advanced(by:) creează o nouă dată adăugând TimeInterval specificat la data curentă. Aceste metode implementează protocolul Strideable, permițând utilizarea Date în intervale Range și ClosedRange.
let start = Date()
let end = start.addingTimeInterval(86400)
// Compararea prin operatori
if start < end {
print("start is earlier")
}
// TimeInterval între două date
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 egal cu 86400 corespunde unei zile. Pentru intervale mai complexe — săptămâni, luni, ani — utilizați Calendar și DateComponents, deoarece aceste unități au lungime variabilă (ani bisecți, trecerea la ora de vară). TimeInterval se aplică doar pentru intervale fixe în secunde.
Calendar — este puntea dintre Date și componentele lizibile pentru om. Calendar transformă Date în DateComponents (an, lună, zi, oră, minut, secundă) ținând cont de fusul orar și localizare. Fără Calendar, nu se poate extrage anul sau luna din Date — Date nu conține aceste informații din cauza naturii sale absolute.
Metoda Calendar.component extrage o singură componentă din Date: an, lună, zi, oră, minut, secundă, weekday, quarter. Metoda Calendar.dateComponents extrage un set de componente într-un singur apel — aceasta este mai eficientă decât apelarea component pentru fiecare câmp în parte.
Calendar.isDateInToday, isDateInTomorrow, isDateInYesterday — metode convenabile pentru verificarea datelor relative. Calendar.dateInterval returnează începutul și sfârșitul perioadei specificate (zi, săptămână, lună, an). Calendar.compare compară datele cu precizia componentei specificate — de exemplu, anul fără a lua în considerare luna și ziua.
let calendar = Calendar.current
// Extragerea componentelor
let year = calendar.component(.year, from: Date())
let month = calendar.component(.month, from: Date())
// Check relative date
if calendar.isDateInToday(someDate) {
print("Today!")
}
// Începutul și sfârșitul zilei
let dayInterval = calendar.dateInterval(of: .day, for: Date())!
print("Day start: \(dayInterval.start)")
print("Day end: \(dayInterval.end)")
Calendar.current utilizează setările de sistem ale utilizatorului — calendarul, fusul orar și localizarea. Pentru testare sau calcule specifice, se poate crea un Calendar cu parametri concreți prin Calendar(identifier: .gregorian) și seta TimeZone-ul dorit prin proprietatea timeZone.
DateFormatter — componentă obligatorie dacă Date trebuie afișat utilizatorului. DateFormatter transformă Date într-un șir conform formatului și localizării specificate. Transformarea directă a Date în șir prin String(describing:) returnează o reprezentare tehnică cu reference date și TimeInterval — nu este destinată utilizatorului.
Abordarea de bază este utilizarea stilurilor predefinite dateStyle și timeStyle. iOS suportă patru stiluri: .short, .medium, .long, .full. Combinarea stilurilor de dată și timp permite configurarea flexibilă a afișării. DateFormatter aplică automat localizarea: pentru localizarea română, data se va afișa în formatul \"21 iulie 2026\".
ISO8601DateFormatter — un formator specializat pentru ISO 8601, cel mai răspândit format pentru API și schimbul de date. Acest formator funcționează mai rapid decât DateFormatter și nu depinde de localizare, ceea ce îl face preferat pentru serializarea datelor în JSON.
// Stiluri predefinite
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
let userString = formatter.string(from: Date())
// ISO 8601 pentru API
let isoFormatter = ISO8601DateFormatter()
let apiString = isoFormatter.string(from: Date())
// Parsare din șir
let parsed = isoFormatter.date(from: "2026-07-21T10:30:00Z")!
Când lucrați cu DateFormatter, este important să ținteți cont de performanță: crearea unui nou formator este o operație costisitoare. Se recomandă stocarea în cache a formatorului sau crearea lui o singură dată și reutilizarea. În proprietățile formatorului se poate seta timeZone — implicit se utilizează fusul orar de sistem, dar pentru datele de server este adesea necesar TimeZone(identifier: \"UTC\").
Să analizăm scenariile tipice de lucru cu Date într-o aplicație iOS. Primul scenariu — calcularea vârstei utilizatorului din data nașterii. Al doilea — cronometrul de numărătoare inversă până la un eveniment. Al treilea — gruparea înregistrărilor după dată pentru afișarea sub formă de secțiuni de tabel.
Calendar.dateComponents cu flagul [.year] calculează diferența dintre două date. Setarea corectă a fusului orar este critică — dacă nu specificați timeZone în Calendar, rezultatul poate diferi cu o zi din cauza trecerii peste miezul nopții într-un alt fus orar.
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
}
Cronometrul de numărătoare inversă se implementează prin TimeInterval. Calculăm diferența dintre data țintă și data curentă, obținem restul în secunde și îl transformăm în zile, ore, minute. Pentru actualizare periodică se utilizează Timer cu un interval de 1 secundă. ObservableObject cu proprietatea @Published permite SwiftUI să actualizeze automat interfața.
Gruparea după dată se implementează printr-un dicționar cu cheia Date. Calendar.dateInterval(of: .day, for:) normalizează data până la începutul zilei, ceea ce permite gruparea înregistrărilor care aparțin aceleiași zile. Aceeași abordare funcționează pentru săptămâni, luni și ani — este suficient să schimbați componenta în dateInterval pe .weekOfYear sau .month.
| Scenariu | API cheie | Caracteristică |
|---|---|---|
| Calcularea vârstei | Calendar.dateComponents | Luați în considerare timeZone |
| Numărătoare inversă | Date.timeIntervalSince | Timer+Combine |
| Gruparea datelor | Calendar.dateInterval | Normalizare până la zi |
| Serializare JSON | ISO8601DateFormatter | Locale nu influențează |
Întrebări frecvente
Date — este o reprezentare internă a timpului fără legătură cu calendarul și localizarea. Un șir este o afișare formatată dependentă de setările utilizatorului. Date poate fi comparat, serializat și procesat matematic cu o precizie de 100%, în timp ce reprezentarea sub formă de șir necesită întotdeauna parsare printr-un formator.
Date — este un marcaj temporal absolut (număr de secunde de la reference date) care nu depinde de fusul orar. Fusul orar este contextul de afișare. Același Date în UTC și în București reprezintă același moment fizic, dar se afișează ca timp calendaristic diferit.
Date este suportat direct de Core Data ca tip de atribut. Core Data serializează automat Date în stocare. Pentru interogări cu filtrare după dată, utilizați NSPredicate cu operatori de comparare — Core Data procesează corect timezone la nivel de SQLite.
CFAbsoluteTime — este un tip Core Foundation care utilizează aceeași dată de referință (1 ianuarie 2001). Date și CFAbsoluteTime sunt interschimbabile prin conversie directă. Date(timeIntervalSinceReferenceDate:) acceptă CFAbsoluteTime, iar Date.timeIntervalSinceReferenceDate returnează CFAbsoluteTime.
Date are precizie până la milisecundă, dar nu garantează precizie la nivel de nanosecundă din cauza limitărilor hardware ale iOS/macOS. Pentru măsurători de înaltă precizie, utilizați mach_absolute_time sau ContinuousClock din Swift 5.7+, care funcționează pe contoare hardware de cicluri ale procesorului.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și