Lekce 11 - Datum a čas v Kotlin - Vytváření a formátování
V předchozím kvízu, Kvíz - Dědičnost, statika, vlastnosti v Kotlin OOP, jsme si ověřili nabyté zkušenosti z předchozích lekcí.
V dnešním tutoriálu se pustíme do dalších tříd, které Kotlin poskytuje pomocí Javy. Ukážeme si, jak se v Kotlinu pracuje s datem a časem.
Datum a čas v Kotlin
Kotlin nemá žádnou vlastní implementaci data a času. Proč by se také vývojáři Kotlinu měli soustředit na něco, co již vytvořil Oracle v Javě 8? Jak jsem zdůrazňoval v úvodní lekci základů Kotlinu, Kotlin a Java jsou "kompatibilní", běží na stejném virtuálním stroji a proto mohou sdílet své třídy. Kotlin pro datum a čas proto využívá javovské třídy.
Bohužel se v minulosti implementace data a času v Javě hned několikrát radikálně změnila a jelikož předešlé pokusy o ni nebyly příliš uspokojivé, rozšířily se dokonce i externí knihovny, které ji nahrazují. Ačkoli vy budete používat tu nejnovější, kterou Oracle představil ve verzi Javy 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řídaDatez balíčkujava.utilbyla 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 - https://docs.oracle.com/…il/Date.htmlCalendar- TřídaCalendarje první náhradou původníhoDatea 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. Pravděpodobně na ni dříve či později narazíte a v tu chvíli se vám bude hodit článek, který je napsaný pro Javu, Datum a čas v Javě pomocí třídy Calendar.LocalDate,LocalTimeaLocalDateTime- Od Javy 8 se objevila třídaLocalDateTimea její varianty jen pro samotné datum a samotný čas. Oproti tříděCalendarje immutable (to zjednodušeně znamená, že s ní lze pracovat pomocí vláken, více dále v kurzu) 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 Date API Javy 8 se touto knihovnou silně inspiruje a vychází
ze stejných konceptů. Joda-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řídy
LocalDateTimea 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/Kotlin programátora. Čekají nás celkem 3 články na toto téma. Tak vzhůru do toho!
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. 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 kurzu) a podobně.
{KOTLIN_OOP}
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.Month
fun main(args: Array<String>) {
// Datum a čas
val datumCas = LocalDateTime.of(2016, Month.APRIL, 15, 3, 15)
println(datumCas)
// Pouze datum
val datum = LocalDate.of(2016, Month.APRIL, 15)
println(datum)
// Pouze čas
val cas = LocalTime.of(3, 15, 10)
println(cas)
}
{/KOTLIN_OOP}
Nezapomeňte jednotlivé třídy naimportovat:
import java.time.LocalDate import java.time.LocalDateTime import java.time.LocalTime import java.time.Month
Výstup:
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 val datumCas = LocalDateTime.now() println(datumCas) // Aktuální datum val datum = LocalDate.now() println(datum) // Aktuální čas val cas = LocalTime.now() 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ě ofPattern().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 jako "d.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 - https://docs.oracle.com/…rmatter.html
Udělejme si příklad:
{KOTLIN_OOP}
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.Month
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
fun main(args: Array<String>) {
val dateTime = LocalDateTime.now()
println(dateTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM)))
println(dateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)))
println(dateTime.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.SHORT)))
println(dateTime.format(DateTimeFormatter.ofPattern("d.M.y H:m:ss")))
}
{/KOTLIN_OOP}
Nezapomeňte si dodat importy:
import java.time.format.DateTimeFormatter import java.time.format.FormatStyle
Výsledek:
20:13:04 Pátek, 9. prosince 2016 9 prosince 2016 20:13 9.12.2016 20:13:04
Datum a čas se bude zobrazovat lokalizován pro jazyk vašeho operačního systému.
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í. Máme k dispozici tyto hodnoty:
FULL- Vrací datum jako Pátek, 6. prosince 2016, pro čas nemá význam a při použití vyvolá výjimku.LONG- Vrací datum jako 6. prosince 2016, pro čas nemá význam a při použití vyvolá výjimku.MEDIUM- Vrací datum jako 6. pros 2016, čas jako 3:15:10.SHORT- Vrací datum jako 6.12.2016, čas jako 3:15.
Na třídě DateTimeFormatter jsou také dostupné
předdefinované formáty jako konstanty, ale české formáty tam
nehledejte.
V příští lekci, Datum a čas v Kotlin - Úprava a intervaly, budeme pokračovat s datem a časem, protože je
to v Kotlin poměrně rozsáhlé téma. Ukážeme si převody mezi
LocalDate, LocalTime a LocalDateTime, jak
upravovat vnitřní hodnotu a také práci s intervaly.

