Lekce 13 - Datum a čas v Javě 8 - Vytváření a formátování
V předešlém cvičení, Řešené úlohy k 12. lekci OOP v Javě, jsme si procvičili nabyté zkušenosti z předchozích lekcí.
V dnešním tutoriálu se pustíme do dalších tříd, které Java poskytuje. Ukážeme si, jak se od Javy 8 pracuje s datem a časem.
Datum a čas v Javě
Implementace data a času se v Javě bohužel v minulosti hned několikrát radikálně změnila a jelikož předešlé pokusy nebyly příliš uspokojivé, rozšířily se dokonce i externí knihovny, které ji nahrazují. Ačkoli vy budete používat tu nejnovější, kterou Java představila ve verzi 8, jistě se časem ve starších projektech setkáte s legacy třídami, které se k tomuto účelu využívaly v minulosti. Jsou to:
- Date - Třída
Date
z balíčkujava.util
byla prvním pokusem o uložení data a času v Javě a nalézá se v ní již jen z důvodu zpětné kompatibility. Téměř všechny její metody jsou označené jako zastaralé a proto se s ní zde nebudeme vůbec zabývat. Pokud ji někde potkáte, bude vám muset stačit oficiální dokumentace. - Calendar - Třída
Calendar
je první náhradou původní třídyDate
a nově přinesla např. lokalizaci a pohodlnější manipulaci s vnitřní hodnotou, mohli jsme jednoduše přičítat časové intervaly a podobně. V nových projektech ji nepoužívejte, ale pravděpodobně na ni dříve či později narazíte a v tu chvíli se vám bude hodit lekce Datum a čas v Javě pomocí třídy Calendar. - LocalDate, LocalTime a
LocalDateTime - Od Javy 8 se objevila třída
LocalDateTime
a její varianty jen pro samotné datum a samotný čas. Oproti tříděCalendar
jeimmutable
(to zjednodušeně znamená, že s ní lze pracovat pomocí vláken, více dále v seriálu) a ctí tzv. fluent interface (někdy překládané do češtiny jako plynulé/tekoucí rozhraní), ale říkejme mu spíše řetězení metod. Také nemíchá získávání a nastavování hodnot v jedné metodě, ale poskytuje k tomuto účelu oddělené metody. Původní kalendář kvalitativně převyšuje a nahrazuje. - Joda-Time - Již zmíněné neúspěšné pokusy o
implementaci data a času do Javy samozřejmě způsobily potřebu kvalitní
náhrady a jako častá alternativa se uchytila knihovna
Joda-Time
. Nelze si nevšimnout, že třídaDate
API Javy 8 se touto knihovnou silně inspiruje a vychází ze stejných konceptů. KnihovnaJoda-Time
je dost možná ještě o něco kvalitnější, ale doporučoval bych držet se spíše již poměrně kvalitní standardní třídyLocalDateTime
a vyhnout se zbytečným závislostem na knihovnách třetích stran.
Velké množství tříd je, ať chceme nebo ne, každodenní chléb Java programátora. Berme to však z té pozitivní stránky, hlavně proto je tato práce asi nejlépe placená ze všech programovacích jazyků. Čekají nás celkem 3 lekce na toto téma. Tak vzhůru do toho!
Třídy
LocalDateTime
, LocalDate
a LocalTime
Již víme, že budeme používat třídy LocalDateTime
,
LocalDate
a LocalTime
a to podle toho, zda
potřebujeme ukládat datum i čas (např. odlet letadla), pouze datum (např.
datum narození) a pouze čas (např. 12:00, přesnost na nanosekundy).
Vytvoření instancí
Začněme tím, jak lze instance jednotlivých tříd vytvořit. Vytvoříme
si nový projekt s názvem DatumACas
.
Vytvoření dle zadání
Když chceme vytvořit novou instanci nějaké ze tříd, zavoláme na
třídě tovární metodu of()
a zadáme
patřičné parametry:
// Datum a čas LocalDateTime datumCas = LocalDateTime.of(2016, Month.APRIL, 15, 3, 15); System.out.println(datumCas); // Pouze datum LocalDate datum = LocalDate.of(2016, Month.APRIL, 15); System.out.println(datum); // Pouze čas LocalTime cas = LocalTime.of(3, 15, 10); System.out.println(cas);
Metoda má více přetížení, např. můžeme a nemusíme zadat vteřiny, měsíc můžeme zadat jak číslem, tak pomocí tzv. výčtového typu (což je asi přehlednější, více se o nich dozvíme dále v seriálu) a podobně.
Nezapomeňme jednotlivé třídy naimportovat:
import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Month;
Výstup:
Konzolová aplikace
2016-04-15T03:15
2016-04-15
03:15:10
Vytvoření dle aktuálního data a času
Ve svých aplikacích budeme samozřejmě potřebovat získat také
aktuální datum a čas. K tomu slouží další tovární metoda
now()
, kterou voláme opět přímo na příslušné třídě:
// Aktuální datum a čas LocalDateTime datumCas = LocalDateTime.now(); System.out.println(datumCas); // Aktuální datum LocalDate datum = LocalDate.now(); System.out.println(datum); // Aktuální čas LocalTime cas = LocalTime.now(); System.out.println(cas);
Formátování
Jelikož výstup není úplně uživatelsky přívětivý, pojďme si
ukázat, jak jej naformátovat. Asi vás nepřekvapí, že k tomu použijeme
metodu format()
již normálně na instanci. Samotné
formátování zajišťuje třída DateTimeFormatter
, nás na ni
budou zajímat tyto statické metody:
ofLocalizedDateTime()
- Zformátuje na lokální formát data a času. Zadáváme dva parametry - styl data a styl času. Máme na výběr plný (full
) až krátký (short
) formát, což platí u všech formátovacích metod kromě metodyofPattern()
.ofLocalizedDate()
- Zformátuje na lokální formát dataofLocalizedTime()
- Zformátuje na lokální formát časuofPattern()
- Oproti metodám výše, které formátovaly dle regionálního nastavení daného uživatele, zde můžeme specifikovat vlastní formát pomocí textového řetězce a zástupných znaků. Např. den, měsíc, rok, hodiny, minuty a sekundy (vše čísly) by se předalo jakod.M.y H:m:ss
. Popis významu všech symbolů by byl zbytečně vyčerpávající a najdete jej v oficiální dokumentaci Javy.
Udělejme si příklad:
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(dateTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM)));
System.out.println(dateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)));
System.out.println(dateTime.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.SHORT)));
System.out.println(dateTime.format(DateTimeFormatter.ofPattern("d.M.y H:m:ss")));
Nezapomeňme si dodat importy:
import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle;
Výstupem je aktuální formátovaný čas:
Konzolová aplikace
20:13:04
Pátek, 9. prosince 2016
9. prosince 2016 20:13
9.12.2016 20:13:04
Všimněte si, že metodám specifikujeme v parametrech i již zmíněný
styl (enum FormatStyle
), který udává zda chceme výpis stručný
až vyčerpávající (ukecaný). Máme k dispozici tyto hodnoty:
FULL
- Vrací datum jakoPátek, 6. prosince 2016
, pro čas nemá význam a při použití vyvolá výjimku.LONG
- Vrací datum jako6. prosince 2016
, pro čas nemá význam a při použití vyvolá výjimku.MEDIUM
- Vrací datum jako6. pros 2016
, čas jako3:15:10
.SHORT
- Vrací datum jako6.12.2016
, čas jako3:15
.
Na třídě DateTimeFormatter
jsou také dostupné
předdefinované formáty jako konstanty, ale české formáty tam bohužel
nenajdeme.
V další lekci, Datum a čas od Javy 8 - Úprava a intervaly si ukážeme převody mezi LocalDate
,
LocalTime
a LocalDateTime
, jak upravovat vnitřní
hodnotu a práci s intervaly.