Při psaní programů stejně tak jako v reálném světe mají datumy svoji nezastupitelnou pozici. Objednávka byla vytvořena v nějaký čas, V nějakou dobu byly zpracovávány konkrétní objednávky atd.
Práce s datem a časem je velmi komplikovaná a hlavním problémem je nejednoznačnost místního času, a to z důvodů:
Různá časová pásma: uživatelé mohou být v různých částech světa
Letní a zimní čas (DST): některé oblasti posouvají čas o hodinu dopředu nebo dozadu
Historické změny časových pásem: časová pásma se historicky měnila, což může ovlivnit starší data
Pokud aplikace ukládá časy v místním čase (například SEČ, EST), může být obtížné tyto hodnoty správně interpretovat, srovnávat nebo převádět při zpracování dat z různých regionů. Řešením je využíván Coordinated Universal Time (UTC).
Koordinovaný světový čas (UTC)
UTC je jednotný světový čas, nezávislý na časových pásmech, který ani není ovlivněn zimním a letním časem. Je vhodný pro ukládání časových údajů, které se budou zpracovávat globálně. UTC je nástupcem GMT (Greenwich Mean Time), ale GMT je astronomický čas, zatímco UTC je řízený atomovými hodinami.
Proč používat UTC?
Jednotný čas na celém světě
Zabraňuje chybám při práci s lokálními časy napříč různými časovými pásmy
Typický problém:
Server běží v jednom časovém pásmu, uživatel je v jiném.
Pokud jsou uloženy časy v lokálním čase, nelze je správně mezi sebou porovnávat.
Příklad problému:
Uživateli v ČR (UTC+1) je uložena objednávka ve 14:00.
Server běží v datacentru v USA (UTC-5) a uloží si čas jako 14:00 lokálně.
Ve skutečnosti se však jedná o dva různé okamžiky!
Proto je důležité vše ukládat v UTC.
Jednoznačná identifikace času
Pro jednoznačnou identifikaci času je nutná kombinace:
UTC čas
Časová zóna (Time Zone)
Offset od UTC (např. +02:00)
Datové typy pro práci s datem a časem
Programovací jazyky pro ukládání informací o datu a času využívají speciální datové typy.
Konkrétně v C# lze využít datové typy:
DateTime – Základní datový typ pro práci s datem a časem.
TimeSpan – Datový typ sloužící pro uložení rozdílu mezi dvěma daty a časy.
DatetimeOffset – Uložení přesného data a času včetně posunu oproti UTC.
DateOnly – Slouží k uložení pouze data.
DateTime
Nejpoužívanějším typem pro práci s datem a časem v .NET je DateTime. V praxi se nejčastěji pracuje s aktuálním časem, který lze získat pomocí vlastností DateTime.Now (lokální čas) nebo DateTime.UtcNow (čas v UTC).
Čas je také možné získat z textového řetězce pomocí statické metody DateTime.TryParse, která bezpečně převede text na instanci typu DateTime.
Typ DateTime poskytuje širokou škálu metod pro manipulaci s datem a časem – například přičítání nebo odečítání dnů, hodin, minut či sekund. Zároveň umožňuje přístup k jednotlivým částem data, jako je den, měsíc, rok nebo hodina. Velkou výhodou je i podpora přestupných let, která je plně zohledněna při výpočtech.
Důležitou součástí práce s datem je i jeho formátování. Pro základní výpis lze využít metody jako ToLongDateString() nebo ToShortDateString(). Pro přesnější nebo vlastní formáty slouží formátovací řetězce, například "yyyy-MM-ddTHH:mm:ss" pro výstup ve formátu ISO 8601.
DateTime now = DateTime.Now;Console.WriteLine(now.ToLongDateString());Console.WriteLine(now.ToString("YYYY-MM-DDTHH:mm:ss"));
Jak získat název dnešního dne?
switch(DateTime.Now.Day){ case 0: Console.WriteLine("Monday"); break; case 1: Console.WriteLine("Tuesday"); break; // atd...}
DateTime není vhodný pro práci s časovými zónami. Pro nejlepší přístup je lepší využít nějaké dodatečné nadstavbové datové typy například z Nuget balíčku: NodaTime
TimeSpan
Datový typ sloužící pro uložení rozdílu uběhlého času mezi dvěma datumy. Jedná se o ideální přístup pro uložení i časového intervalu.
int minutes = 60;// lépeTimeSpan minutes = TimeSpan.FromMinutes(60);
Pozor na ukládání informací v TimeSpanu
V rámci TimeSpan se čas vždy převádí na vyšší jednotky – tzn. 60 minut se převede na 1 hodinu. Pro získání informace o celkovém počtu minut v TimeSpanu, je nutné využít vlastnost TotalMinutes. Při využití Minutes bude výsledek 0, protože čas je uložen jako 1 hodina 0 minut.