Date — je struktura Foundation představující konkrétní okamžik v čase nezávisle na kalendáři a časovém pásmu. Typ ukládá počet sekund, které uplynuly od referenčního data 1. ledna 2001 (reference date), a poskytuje základní operace porovnávání a výpočtu časových intervalů. Podle Apple Developer Documentation (2025) se Date používá ve všech frameworkích Apple: od UIKit a SwiftUI po CloudKit a Core Data. Porozumění fungování Date je povinné pro každého iOS vývojáře, protože bez něj nelze spravovat čas v aplikaci.
Hlavní body
Date — je hodnotový typ z frameworku Foundation, který zaznamenává jeden absolutní okamžik v čase. Na rozdíl od kalendářních reprezentací (rok, měsíc, den) Date nezávisí na časovém pásmu a kalendářním systému — je to čistě numerická hodnota časového razítka.
Vnitřní reprezentace Date je TimeInterval (alias pro Double) ukládající počet sekund vzhledem k referenčnímu datu — 1. lednu 2001 00:00:00 UTC. Apple zvolil toto datum místo Unix epoch (1970) pro kompatibilitu se starými systémy NeXTSTEP, na kterých jsou postaveny iOS a macOS.
Date se používá jako standardní časový typ ve všech Apple API: UIDatePicker, DatePicker, UserDefaults, Codable, Core Data, CloudKit. Bez Date nelze pracovat s rozvrhy, časovači, kalendářními událostmi, serializací dat a jakýmikoli operacemi souvisejícími s časem.
Date se liší od kalendářních typů tím, že představuje fyzické časové razítko, nikoli hodnotu čitelnou pro člověka. Stejné Date může odpovídat různým kalendářním datům v různých časových pásmech. Pro získání komponent (rok, měsíc, den) se Date převádí přes Calendar a DateComponents.
Date se také liší od DispatchTime, který se používá pro odesílání úkolů v Grand Central Dispatch. DispatchTime je relativní vůči okamžiku spuštění systému, zatímco Date je absolutní razítko, které lze ukládat, přenášet a obnovovat.
Date() — je nejjednodušší způsob, jak vytvořit objekt s aktuálním časovým okamžikem. Inicializátor bez argumentů vrací přesný čas volání. Pro vytvoření data v minulosti nebo budoucnosti se používá TimeInterval a metoda addingTimeInterval nebo inicializace z existujícího Date.
Pro vytvoření libovolného data z komponent se používá dvojice Calendar a DateComponents. Calendar převádí pro člověka čitelné komponenty (rok, měsíc, den, hodina, minuta) na Date. Také lze inicializovat Date prostřednictvím ISO8601DateFormatter z řetězce ve formátu ISO 8601 nebo prostřednictvím DateFormatter z libovolné řetězcové reprezentace.
Date.distantPast a Date.distantFuture — dvě statické vlastnosti představující nekonečně vzdálené okamžiky minulosti a budoucnosti. Používají se jako hraniční hodnoty při filtrování a řazení dat v algoritmech.
import Foundation
// Vytvoření Date s aktuálním časem
let now = Date()
print("Current time: \(now)")
// Datum za 1 hodinu (3600 sekund)
let inOneHour = now.addingTimeInterval(3600)
// Datum z komponent
var components = DateComponents()
components.year = 2025
components.month = 12
components.day = 25
let christmas = Calendar.current.date(from: components)!
V příkladu jsou ukázány tři způsoby vytvoření Date: aktuální čas, přidání intervalu a vytvoření prostřednictvím DateComponents. Všechny tři přístupy vracejí hodnotu typu Date s přesností na milisekundu. Calendar.current používá systémový kalendář uživatele — na zařízeních Apple je to obvykle gregoriánský kalendář.
TimeInterval — je alias pro Double představující počet sekund mezi dvěma časovými okamžiky. Přesnost TimeInterval dosahuje zlomků milisekundy, což je dostačující pro většinu aplikací. Záporná hodnota TimeInterval označuje minulost vůči referenčnímu bodu.
Date podporuje všechny standardní porovnávací operátory: ==, <, >, <=, >=. Swift automaticky porovnává vnitřní TimeInterval hodnot. Metoda compare vrací ComparisonResult s variantami .orderedSame, .orderedAscending, .orderedDescending pro explicitnější porovnání.
Date.distance(to:) — metoda vracející TimeInterval k uvedenému datu. Pokud je cílové datum v minulosti, výsledek je záporný. advanced(by:) vytváří nové datum přidáním uvedeného TimeInterval k aktuálnímu datu. Tyto metody implementují protokol Strideable a umožňují použití Date v rozsazích Range a ClosedRange.
let start = Date()
let end = start.addingTimeInterval(86400)
// Porovnání pomocí operátorů
if start < end {
print("start is earlier")
}
// TimeInterval mezi dvěma daty
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 rovný 86400 odpovídá jednomu dni. Pro složitější intervaly — týdny, měsíce, roky — použijte Calendar a DateComponents, protože tyto jednotky mají proměnlivou délku (přestupné roky, změna na letní čas). TimeInterval se používá pouze pro pevné intervaly v sekundách.
Calendar — je mostem mezi Date a pro člověka čitelnými komponentami. Calendar převádí Date na DateComponents (rok, měsíc, den, hodina, minuta, sekunda) s přihlédnutím k časovému pásmu a locale. Bez Calendar nelze z Date extrahovat rok ani měsíc — Date kvůli své absolutní povaze tyto informace neobsahuje.
Metoda Calendar.component extrahuje jednu komponentu z Date: rok, měsíc, den, hodina, minuta, sekunda, weekday, quarter. Metoda Calendar.dateComponents extrahuje sadu komponent v jednom volání — to je efektivnější než volat component pro každé pole zvlášť.
Calendar.isDateInToday, isDateInTomorrow, isDateInYesterday — pohodlné metody pro kontrolu relativních dat. Calendar.dateInterval vrací začátek a konec uvedeného období (den, týden, měsíc, rok). Calendar.compare porovnává data s přesností uvedené komponenty — například rok bez ohledu na měsíc a den.
let calendar = Calendar.current
// Extrahování komponent
let year = calendar.component(.year, from: Date())
let month = calendar.component(.month, from: Date())
// Check relative date
if calendar.isDateInToday(someDate) {
print("Today!")
}
// Začátek a konec dne
let dayInterval = calendar.dateInterval(of: .day, for: Date())!
print("Day start: \(dayInterval.start)")
print("Day end: \(dayInterval.end)")
Calendar.current používá systémová nastavení uživatele — kalendář, časové pásmo a locale. Pro testování nebo specifické výpočty lze vytvořit Calendar s konkrétními parametry pomocí Calendar(identifier: .gregorian) a nastavit požadované TimeZone prostřednictvím vlastnosti timeZone.
DateFormatter — povinná součást, pokud má být Date zobrazeno uživateli. DateFormatter převádí Date na řetězec podle uvedeného formátu a locale. Přímý převod Date na řetězec pomocí String(describing:) vrací technickou reprezentaci s reference date a TimeInterval — ta není určena pro uživatele.
Základním přístupem je použití předdefinovaných stylů dateStyle a timeStyle. iOS podporuje čtyři styly: .short, .medium, .long, .full. Kombinace stylů data a času umožňuje flexibilní přizpůsobení zobrazení. DateFormatter automaticky aplikuje lokalizaci: pro českou locale se datum zobrazí ve formátu \"21. července 2026\".
ISO8601DateFormatter — specializovaný formátovač pro ISO 8601, nejrozšířenější formát pro API a výměnu dat. Tento formátovač pracuje rychleji než DateFormatter a nezávisí na locale, což jej činí preferovaným pro serializaci dat v JSON.
// Předdefinované styly
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
let userString = formatter.string(from: Date())
// ISO 8601 pro API
let isoFormatter = ISO8601DateFormatter()
let apiString = isoFormatter.string(from: Date())
// Parsování z řetězce
let parsed = isoFormatter.date(from: "2026-07-21T10:30:00Z")!
Při práci s DateFormatter je důležité pamatovat na výkon: vytvoření nového formátovače je nákladná operace. Doporučuje se formátovač ukládat do mezipaměti nebo jej vytvořit jednou a znovu používat. Ve vlastnostech formátovače lze nastavit timeZone — ve výchozím nastavení se používá systémové časové pásmo, ale pro serverová data je často vyžadováno TimeZone(identifier: \"UTC\").
Podívejme se na typické scénáře práce s Date v iOS aplikaci. První scénář — výpočet věku uživatele z data narození. Druhý — časovač odpočítávání do události. Třetí — seskupování záznamů podle data pro zobrazení jako sekcí tabulky.
Calendar.dateComponents s příznakem [.year] vypočítává rozdíl mezi dvěma daty. Nastavení správného časového pásma je kritické — pokud v Calendar neuvedete timeZone, výsledek se může lišit o jeden den kvůli překročení půlnoci v jiném časovém pásmu.
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
}
Časovač odpočítávání se implementuje pomocí TimeInterval. Vypočítáme rozdíl mezi cílovým a aktuálním datem, získáme zbytek v sekundách a převedeme na dny, hodiny, minuty. Pro pravidelnou aktualizaci se používá Timer s intervalem 1 sekunda. ObservableObject s vlastností @Published umožňuje SwiftUI automaticky aktualizovat rozhraní.
Seskupování podle data se implementuje pomocí slovníku s klíčem Date. Calendar.dateInterval(of: .day, for:) normalizuje datum na začátek dne, což umožňuje seskupit záznamy patřící ke stejnému dni. Stejný přístup funguje pro týdny, měsíce a roky — stačí změnit komponentu v dateInterval na .weekOfYear nebo .month.
| Scénář | Klíčové API | Vlastnost |
|---|---|---|
| Výpočet věku | Calendar.dateComponents | Zohlednit timeZone |
| Odpočítávání | Date.timeIntervalSince | Timer+Combine |
| Seskupování dat | Calendar.dateInterval | Normalizace na den |
| Serializace JSON | ISO8601DateFormatter | Locale neovlivňuje |
Často kladené otázky
Date — je vnitřní reprezentace času bez vazby na kalendář a locale. Řetězec je formátovaný pohled závislý na nastavení uživatele. Date lze porovnávat, serializovat a matematicky zpracovávat se stoprocentní přesností, zatímco řetězcová reprezentace vždy vyžaduje parsování přes formátovač.
Date — je absolutní časové razítko (počet sekund od reference date), které nezávisí na časovém pásmu. Časové pásmo je kontext zobrazení. Stejné Date v UTC a v Praze představuje stejný fyzický okamžik, ale zobrazuje se jako jiný kalendářní čas.
Date je přímo podporováno Core Data jako typ atributu. Core Data automaticky serializuje Date v úložišti. Pro dotazy s filtrováním podle data použijte NSPredicate s porovnávacími operátory — Core Data správně zpracovává timezone na úrovni SQLite.
CFAbsoluteTime — je typ Core Foundation používající stejné referenční datum (1. ledna 2001). Date a CFAbsoluteTime jsou vzájemně zaměnitelné přímou konverzí. Date(timeIntervalSinceReferenceDate:) přijímá CFAbsoluteTime a Date.timeIntervalSinceReferenceDate vrací CFAbsoluteTime.
Date má přesnost až na milisekundu, ale nezaručuje nanosekundovou přesnost kvůli hardwarovým omezením iOS/macOS. Pro vysoce přesná měření použijte mach_absolute_time nebo ContinuousClock ze Swift 5.7+, které pracují na hardwarových počítadlech cyklů procesoru.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také