NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.

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, uvědomíme si, že vše je v podstatě doba, jež uběhla od nějakého počátečního bodu. Proto Microsoft zvolil jeden společný typ pro datum i čas. Třída DateTime 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. Založíme si projekt s názvem DatumACas. Nejprve si vytvoříme instanci pomocí bezparametrického konstruktoru:

DateTime datumCas = new DateTime();
Console.WriteLine(datumCas);
Console.ReadKey();

Výstupem programu bude toto:

Konzolová aplikace
01.01.0001 0:00:00

Nyní si ukažme dva nejzákladnější konstruktory, pomocí nichž 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:

DateTime datumCas = new DateTime(2016, 7, 15);
Console.WriteLine(datumCas);

A výstup:

Konzolová aplikace
15.07.2016 0:00:00

Pokud si budeme přát zadat 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ěží, proto potřebujeme-li po nějaké době opět aktuální čas, musíme si pomocí Now vytvořit instanci novou. Pojďme si to zkusit:

DateTime datumCas = DateTime.Now;
Console.WriteLine("Dnes je: {0}", datumCas);
Console.ReadKey();

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 jsou datum i čas vlastně interně uloženy. Jedná se o velmi vysoké číslo, jeden tick reprezentuje sto nanosekund, tedy desetimiliontinu sekundy. To se vám někdy může 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 do řetězce string.
  • DayOfYear – Den v roce, vrací tedy hodnoty 1366.

Z DateTime můžeme oddělit složku s časem a ten nastavit na 0:00:00. Slouží k tomu vlastnost Date, která vrátí DateTime s původním datem a bez času. To může 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:

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();

Výsledek:

Konzolová aplikace
Dnes je Monday 6.
Je 3. měsíc a rok 2023.
7 hodin, 40 minut a 47 sekund.

Kvůli tomu, že máme anglický operační systém, C# vrací také 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 dny zobrazily správně dle jeho regionálního nastavení, C# to udělá za nás.

Metody

Nyní se podívejme na metody. Pozor, metody instanci DateTime nemění, ale vracejí 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 chceme úseky naopak ubrat, použijeme zápornou hodnotu. Za účelem změny hodnoty tedy slouží metody:

  • AddDays(),
  • AddMonths(),
  • AddYears(),
  • AddHours(),
  • AddMinutes(),
  • AddSeconds(),
  • AddMilliseconds(),
  • AddTicks().

Můžeme se také 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, jež vrací počet dní v zadaném měsíci. Parametry jsou rok a měsíc (rok metoda potřebuje kvůli únoru v přestupném roce).
  • IsLeapYear() – Vrací true pro přestupný rok, parametrem je rok.

Parsování a převod na text

Pravděpodobně 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". Pokud nezadáme čas, nic se nestane, jeho formát bude 0:00:00.

Chceme-li zadávaný formát ovlivnit, musíme k tomu použít 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 proto odkážeme 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);

Máme samozřejmě také k dispozici podobnou metodu TryParseExact().

Nyní se podívejme na převod data do textu, který 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 čtyři formáty, dva pro výpis pouze data a dva pro výpis pouze č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ů > < == (data a čas jsou interně vlastně velmi vysoká čísla s počtem ticks, je tedy velmi jednoduché je porovnávat).

Určitě se podívejte na cvičení k této lekci, obsahuje totiž 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 při zadání času, avšak přidá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, pouze jsme chtěli 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ě struktura TimeSpan. Ta slouží k uchovávání rozdílu mezi dvěma daty. Rozdíl oproti DateTime spočívá v tom, že zatímco DateTime reprezentuje celé datum (bod na časové ose), TimeSpan reprezentuje nějaký interval (ať už jsou to roky, nebo sekundy).

Na DateTime existuje vlastnost TimeOfDay, která vrátí TimeSpan s časem a datum zahodí.

TimeSpan vznikne tehdy, když odečteme dvě instance DateTime. TimeSpan můžeme také k DateTime přičíst pomocí metody Add() na instanci DateTime.

Vlastnosti

K jednotlivým složkám struktury TimeSpan se dostaneme pomocí vlastností (stejně jako u DateTime, pouze v množném čísle):

  • Days,
  • Hours,
  • Minutes,
  • Seconds,
  • Milliseconds,
  • Ticks.

Chceme-li celý interval vyjádřit v jedné jednotce, použijeme vlastnosti předsazené Total. Na rozdíl od výše uvedených vracejí typ 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á k jedné struktuře TimeSpan přidá 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í totéž jako u 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 uživatelův věk. Řekneme mu také to, kolik mu je dní a hodin. Výpočet věku provedeme 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í nemusí výpočet správně fungovat, ale to nás nyní příliš nezatěžuje, pouze si chceme TimeSpan vyzkoušet:

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();

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 zase 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 984x (61.88 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

Předchozí článek
Kvíz - Dědičnost, statika, vlastnosti v C# .NET OOP
Všechny články v sekci
Objektově orientované programování v C# .NET
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 11. lekci OOP v C# .NET
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
434 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity