Lekce 11 - Datum a čas v C# - DateTime
V předchozím kvízu, Kvíz - Dědičnost, statika, vlastnosti v C# .NET OOP, jsme si ověřili nabyté zkušenosti z předchozích lekcí.
DateTime
Pro práci s datem a časem slouží v .NET frameworku třída
DateTime
. Použijeme ji jako datový typ pro uložení data nebo
času. Když se zamyslíme nad pojetím data a času, tak vše je v podstatě
čas, uběhnutý od nějakého počátečního bodu. Proto Microsoft zvolil
jeden společný typ pro datum i pro čas. Třída je poměrně chytrá a má
mnoho užitečných vlastností a metod. My si je zde dnes ukážeme.
Vytvoření instance
Začněme tím, jak lze instanci DateTime
vytvořit. Vytvoříme
si projekt s názvem DatumACas
. Nejprve si vytvoříme instanci
pomocí bezparametrického konstruktoru:
{CSHARP_CONSOLE}
DateTime datumCas = new DateTime();
Console.WriteLine(datumCas);
Console.ReadKey();
{/CSHARP_CONSOLE}
Výstupem programu bude něco takového:
Konzolová aplikace
01.01.0001 0:00:00
Nyní si ukažme 2 nezákladnější konstruktory, pomocí kterých můžeme
instanci DateTime
vytvořit.
Nejprve vytvořme samotné datum bez času (tedy přesněji čas se nebude
nastavovat a zůstane 0:00:00
). Specifikujeme rok, měsíc a
den:
{CSHARP_CONSOLE}
DateTime datumCas = new DateTime(2016, 7, 15);
Console.WriteLine(datumCas);
{/CSHARP_CONSOLE}
A výstup:
Konzolová aplikace
15.07.2016 0:00:00
Pokud si budeme přát zadat i datum i čas, můžeme čas připsat ve formátu:
DateTime datumCas = new DateTime(2016, 7, 15, 3, 15, 0);
Nyní je čas nastaven na 3:15 ráno.
Určitě je důležité vědět, jak se dostaneme k aktuálnímu datu a
času. Slouží k tomu statická vlastnost Now
, která nám
vrátí instanci DateTime
, nastavenou na současný čas.
Voláme ji pochopitelně přímo na třídě. Čas v této instanci již
neběží, když potřebujeme po nějaké době opět aktuální čas,
musíme si vytvořit pomocí Now
novou instanci. Pojďme si to
zkusit:
{CSHARP_CONSOLE}
DateTime datumCas = DateTime.Now;
Console.WriteLine("Dnes je: {0}", datumCas);
Console.ReadKey();
{/CSHARP_CONSOLE}
A výstup:
Konzolová aplikace
Dnes je: 06.03.2023 14:40:23
Podobná je vlastnost Today
, která vrátí
aktuální datum a čas nastavený na 0:00:00
.
Další vlastnosti
Jak již bylo řečeno, DateTime
má mnoho vlastností, které
slouží k přístupu k jednotlivým složkám data a času:
Day
Month
Year
Hour
Minute
Second
Millisecond
Můžeme se zeptat ještě na tzv. Ticks
, ve kterých je datum a
čas vlastně interně uložen. Jedná se o velmi vysoké číslo, jeden tick
reprezentuje sto nanosekund, tedy desetimiliontinu vteřiny. Může se vám to
někdy hodit pro velmi přesné výpočty.
Kromě složek nám .NET umožňuje zjistit:
DayOfWeek
- Vrací den v týdnu v tzv. výčtovém typu, který si vysvětlíme v dalších lekcích C# kurzu. Zatím si řekneme, že výstupní hodnotou může být např.DayOfWeek.Monday
. Při výpisu se podle regionálního nastavení systému převede dostring
u.DayOfYear
- Den v roce, tedy vrací hodnoty1
-366
.
Z DateTime můžeme oddělit složku s časem a nastavit ho na
0:00:00
, slouží k tomu vlastnost
Date
, která vrátí DateTime
s
původním datem a bez času. Může to být užitečné, když pracujeme s
celými dny a čas by nám způsoboval nepřesnosti.
Vyzkoušejme si vlastnosti na dalším programu:
{CSHARP_CONSOLE}
DateTime datumCas = DateTime.Now;
Console.WriteLine("Dnes je {0} {1}.", datumCas.DayOfWeek, datumCas.Day);
Console.WriteLine("Je {0}. měsíc a rok {1}.", datumCas.Month, datumCas.Year);
Console.WriteLine("{0} hodin, {1} minut a {2} sekund.", datumCas.Hour, datumCas.Minute, datumCas.Second);
Console.ReadKey();
{/CSHARP_CONSOLE}
Výsledek:
Konzolová aplikace
Dnes je Monday 6.
Je 3. měsíc a rok 2023.
7 hodin, 40 minut a 47 sekund.
Díky tomu, že mám anglický operační systém, C# vrací i anglická jména dní. Vy je budete mít česká. Toto je výhodné, protože se nemusíme starat o to, aby se každému zobrazily správně, dle jeho regionálního nastavení, C# to za nás udělá.
Metody
Nyní se podívejme na metody. Pozor, metody nemění instanci
DateTime
, ale vrací novou, ve které jsou dané změny
provedeny!
Změna vnitřní hodnoty
S vnitřní hodnotou data a času můžeme velmi jednoduše manipulovat pomocí metod, které přidávají různé časové úseky. Jako parametr berou počet úseků (např. dní), které chceme přidat. Pokud je chceme naopak ubrat, použijeme zápornou hodnotu. Za účelem změny hodnoty tedy slouží metody:
AddDays()
AddMonths()
AddYears()
AddHours()
AddMinutes()
AddSecond()
AddMilliseconds()
AddTicks()
Můžeme se zeptat, zda je daná instance DateTime
ve formátu
letního času:
IsDaylightSavingTime()
Statické metody
Samotná třída má na sobě také statické metody:
DaysInMonth()
- Statická metoda vracející počet dní v zadaném měsíci. Parametry jsou rok a měsíc (rok proto, že mohl být přestupný únor).IsLeapYear()
- Vracítrue
pro přestupný rok, parametrem je rok.
Parsování a převod na text
Asi se nám bude často stávat, že budeme chtít po uživateli zadat
nějaké datum, případně i čas. DateTime
má pro tyto účely
jak metodu Parse()
, tak i TryParse()
.
V nejjednodušší podobě načteme datum a čas takto:
DateTime datum = DateTime.Parse(Console.ReadLine());
Formát data a času potom závisí na regionálním nastavení, většinou
se očekává např. "1.1.2012 13:00"
. Když nezadáme čas, nic se
nestane, jen tam bude 0:00:00
.
Když chceme zadávaný formát ovlivnit, použijeme k tomu tzv. pattern. Ten může mít např. následující podobu:
string pattern = "dd.M.yyyy";
Tabulka těchto hodnot je poněkud vyčerpávající, zájemce odkáži na oficiální dokumentaci, kde jsou vysvětleny jednotlivé složky patternu: http://msdn.microsoft.com/…kb3ddd4.aspx
K parsování poté použijeme metodu ParseExact()
a předáme
jí náš pattern takto:
DateTime datum = DateTime.ParseExact(Console.ReadLine(), pattern, null);
I ta má samozřejmě podobnou metodu TryParseExact()
.
Nyní se podívejme na převod data do textu, ten nám bude užitečný
zejména při výpisu data. Samozřejmě funguje metoda
ToString()
, která je bez parametrů a C# ji volá
implicitně. Metodě můžeme dát jako parametr pattern, aby vrátila datum v
námi požadovaném formátu:
datumCas.ToString("MMMM dd, yyyy");
Předpřipravené máme 4 formáty, 2 pro výpis jen data a 2 pro výpis jen času. Vypisovat můžeme v dlouhém nebo krátkém formátu:
ToShortDateString()
ToShortTimeString()
ToLongDateString()
ToLongTimeString()
Data i čas můžeme běžně porovnávat pomocí operátorů
>
<
==
(interně je to
vlastně velmi vysoké číslo s počtem ticks, data je tedy velmi jednoduché
porovnávat).
Určitě se podívejte na cvičení k této lekci, obsahuje několik důležitých úloh na nejčastější operace s datem a časem.
Jak jistě víte, čas může být vyjádřen jako lokální
(tak, jak je v naší časové zóně) nebo jako mezinárodní (tzv. formát
UTC). Tutoriál nepředpokládá práci s mezinárodním časem. Pokud si budete
přát zjistit aktuální čas v UTC, použijte statickou vlastnost
UtcNow
. Jakého typu je hodnota v DateTime
se můžeme
zeptat pomocí vlastnosti Kind
. Pro vytvoření
DateTime
v UTC použijeme konstruktor jako se zadáním času,
avšak zadáme i další parametr s kind. Typ DateTime
můžeme
změnit pomocí statické metody SpecifyKind()
. Zatím se tím zde
nebudeme zabývat, jen jsem chtěl navést případné zájemce na správné
metody. Mezi těmito dvěma časy můžeme také převádět pomocí metod
ToLocalTime()
a ToUniversalTime().
TimeSpan
S DateTime
souvisí ještě TimeSpan
. Ten slouží
k uchovávání rozdílu mezi dvěma daty. Rozdíl oproti DateTime
je v tom, že DateTime
reprezentuje celé datum
(bod na časové ose), TimeSpan
reprezentuje
nějaký interval (ať už jsou to roky nebo vteřiny).
Na DateTime
existuje vlastnost
TimeOfDay
, která vrátí TimeSpan
s
časem a datum zahodí.
TimeSpan
vznikne, když odečteme 2 instance
DateTime
**. TimeSpan
můžeme také k
DateTime
přičíst pomocí metody Add()
na instanci
DateTime
.
Vlastnosti
K jednotlivým složkám TimeSpan
u se dostaneme pomocí
vlastností (stejně, jako u DateTime
, pouze jsou v množném
čísle):
Days
Hours
Minutes
Seconds
Milliseconds
Ticks
Pokud chceme celý interval vyjádřit v jedné jednotce, použijeme
vlastnosti předsazené Total
. Na rozdíl od výše uvedených
vrací double
, nikoli int
:
TotalDays
TotalHours
TotalMinutes
TotalSeconds
TotalMilliseconds
Metody
TimeSpan
má několik konstruktorů, ukážeme si dva
nejzákladnější:
TimeSpan ts = new TimeSpan(hodiny, minuty, sekundy); TimeSpan ts = new TimeSpan(dny, hodiny, minuty, sekundy);
Metody jsou podobné, jako na třídě DateTime
, opět tu máme
metodu Add()
, která přidá k TimeSpan
u další
TimeSpan
. TimeSpan
můžeme vytvořit statickými
metodami z intervalu v různých jednotkách:
FromDays()
FromHours()
FromMinutes()
FromSeconds()
FromMilliseconds()
Pro Parse()
a ToString()
platí to samé, jako pro
DateTime
.
Pojďme si udělat ještě jeden příklad. Zeptáme se uživatele na jeho
datum narození a z toho vypočítáme jeho věk. Řekneme mu i, kolik mu je
dní a hodin. Výpočet věku uděláme zjednodušený. TimeSpan
bohužel neposkytuje zjištění let (kvůli tomu, že rok má vždy jiný
počet dní), dostaneme se pouze k počtu dní v intervalu. Dny vydělíme
365.255
a zaokrouhlíme dolů. Pro nepatrné množství dat
narození to nemusí fungovat, ale to nás nyní příliš nezatěžuje, jen si
chceme TimeSpan
vyzkoušet:
{CSHARP_CONSOLE}
Console.WriteLine("Zadej datum narození: ");
DateTime narozen = DateTime.Parse(Console.ReadLine());
TimeSpan vek = DateTime.Today - narozen;
Console.WriteLine("Je ti {0} let", Math.Floor(vek.Days/365.255));
Console.WriteLine("To je ve dnech {0} a v hodinách {1}", vek.TotalDays, vek.TotalHours);
Console.ReadKey();
{/CSHARP_CONSOLE}
Konzolová aplikace
Zadej datum narození:
5.6.1989
Je ti 23 let
To je ve dnech 10136 a v hodinách 243264
Všimněte si, že TimeSpan
vznikne opravdu pouhým odečtením
dvou DateTime
. Až budeme zas někdy tvořit objekty uživatelů,
budeme u nich ukládat místo věku datum narození. Z něj poté dokážeme
věk jednoduše spočítat a tak bude stále aktuální. Můžete si to
zkusit.
V následujícím cvičení, Řešené úlohy k 11. lekci OOP v C# .NET, si procvičíme nabyté zkušenosti z předchozích lekcí.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 980x (61.88 kB)
Aplikace je včetně zdrojových kódů v jazyce C#