13. diel - Dátum a čas od Javy 8 - Úprava a intervaly
V minulej lekcii, Dátum a čas v Jave 8 - Vytváranie a formátovanie , sme sa naučili vytvárať inštancie tried
LocalDate
, LocalTime
a LocalDateTime
a
formátovať ich hodnotu.
V dnešnom tutoriáli sa budeme venovať úprave tejto hodnoty a zabehneme aj do časových intervalov.
Potrebné importy
Aby som zbytočne neopakoval, o aké importy v príkladoch ide, naimportujte si ich rovno všetky, ktoré použijeme:
Prevody
Na úvod si ukážme, ako môžeme prevádzať medzi dátumami z inštancií
LocalDate
, LocalTime
a LocalDateTime
.
Konvertovať z
LocalDateTime
Z dátumu LocalDateTime
prevádzame jednoducho pomocou jeho
metód toLocalDate()
a toLocalTime()
.
Konvertovať na
LocalDateTime
Inštanciu LocalDateTime
vytvoríme pomocou jednej z
of()
metód, kde uvedieme zvlášť dátum a čas, napr. takto:
Výstup:
Ak chceme nastaviť čas na
začiatok dňa, môžeme využiť metódu atStartOfDay()
. Ďalšou
metódou, ktorú môžeme vziať dátum a pripojiť k nemu čas, je
atTime()
. Pri tejto metóde si môžeme nastaviť vlastnú hodinu a
minútu. Ďalší variant príkladu vyššie by teda bol:
Na výstupe bude teda začiatok dňa (00:00 hodín) a ďalší čas bude o 10 hodine ako pri minulom príklade:
Úprava hodnoty
K existujúcej inštancii môžeme pripočítať určitý počet dní, hodín
a podobne. Slúžia na to metódy začínajúce na plus...()
alebo
minus...()
, snáď netreba vysvetľovať čo robia. Dôležitá
poznámka je, že vracajú novú inštanciu s upravenou
hodnotou. Inštancia je vo všetkých ohľadoch
nemeniteľná (immutable
) a akákoľvek zmena
spočíta v nahradení za novú (napr. podobne ako to je v Jave s textovými
reťazcami).
Skúsme si to a pridajme aktuálnemu dátumu ďalšie 3 dni v týždni:
Ak si predstavíme, že je
dnes 19.4.2023
, výstupom bude:
Metódy, ktoré máme k dispozícii, sú nasledujúce:
minusDays()
minusHours()
minusMinutes()
minusMonths()
minusNanos()
- Odoberie z času nanosekundy.minusSeconds()
minusWeeks()
minusYears()
plusDays()
plusHours()
plusMinutes()
plusMonths()
plusNanos()
plusSeconds()
plusWeeks()
plusYears()
plusDays(-3)
, je táto metóda rovnaká ako
minusDays(3)
.
Triedy Period
a
Duration
Okrem vyššie spomenutých metód nájdeme aj 4 všeobecné verzie metód
minus()
a plus()
, ktoré prijímajú interval na
pridanie/odobratie. Využijeme ich najmä v prípade, keď dopredu nevieme, či
budeme pridávať napr. dni alebo roky, ušetrí nám veľa podmienkovania.
Máme k dispozícii triedy Duration
a Period
, na
ktorých si môžeme nechať vrátiť objekt reprezentujúci takýto
interval.
Až sa dostaneme k rozhraniam, môžete sa pozrieť, že obe
triedy implementujúce spoločné rozhranie TemporalAmount
. Zatiaľ
si s nimi však nemotajme hlavu.
Upravený kód nášho príkladu by vyzeral takto:
Výstup bude rovnaký, ako
pri príklade vyššie. of...()
metódy majú rovnaké "prípony"
ako mali plus/mínus metódy vymenované vyššie>
Trieda Duration
na rozdiel od triedy Period
označuje nejaký časový interval,
ktorý vôbec nesúvisí s kalendárom (napr. ako dlho trvá vyrobiť
automobil), deň trvá vždy 24 hodín. Trieda Period
počíta s
prechodom na letný čas, deň teda môže niekedy trvať 23 alebo 25 hodín.
Period
použijeme pri práci s triedami LocalDate
/
LocalDateTime
, triedu Duration
pri práci s
časom.
Trieda ChronoUnit
Pre ľahšiu prácu s rôznymi jednotkami ako sú dni, hodiny, minúty a
podobne je nám k dispozícii trieda ChronoUnit
. Vnútorne
používa triedu Duration
. Ide teda iba o iný zápis už
predchádzajúcich úloh, ale len pre istotu, keby ste ho niekedy stretli,
ukážme si ho:
Len pre
úplnosť si dodajme, že trieda ChronoUnit
implementuje rozhranie
TemporalUnit
, keby ste sa s ním neskôr stretli. Teraz rozhranie
riešiť nebudeme.
Ako môžeme vidieť, implementácia dátumu a času je v Jave pomerne zložitá, nebudeme tu zabiehať do zbytočných detailov a zameriame sa najmä na praktickú stránku použitia, ako to u nás na sieti väčšinou robíme.
Ďalšie metódy
Ukážme si ešte ďalšie užitočné metódy.
Metóda between()
Ďalšia metóda, ktorú máme k dispozícii, je statická metóda
between()
na triede Period
, ktorá nám umožňuje
získať interval, teda rozdiel medzi 2 dátumami (presnejšie objekty s
rozhraním Temporal
, to je spoločný typ pre triedy
LocalDate
, LocalDateTime
a
LocalTime
):
Výstup:
Tú istú metódu nájdeme aj
na triede Duration
, ktorá však pracuje s triedou
LocalDateTime
namiesto triedy LocalDate
. Z intervalu
nezistíme počet rokov, pretože roky nemajú pevný počet dní a my už
vieme, že Duration
nie je nijako spojená s kalendárnym poňatím
času.
Metóda until()
Ako posledná stojí za zmienku metóda until()
. Táto metóda
sa volá priamo nad inštanciami tried LocalDate
,
LocalDateTime
a LocalTime
a vracia rovnaký výsledok,
ako statická metóda between()
.
Výstup je rovnaký:
Nastavenie hodnoty
Hodnotu nastavujeme pomocou metód with...*()
, majú opäť tie
isté "prípony" ako metódy doposiaľ spomínané. Ako vždy nezabudnite, že
ako všetky podobné metódy vracajú novú inštanciu:
Reťazenie metód
Vrátenie nových inštancií, ktoré je najmä výsledkom toho, že sú inštancie immutable, zároveň poskytuje tzv. fluent interface (slovensky niekedy prekladané ako plynulé rozhranie). Jedná sa o reťazenie metód, anglicky method chaining. Nehľadajte v tom žiadnu zložitosť, ide len o to, že môžeme väčšinu metód volať po sebe na jednom riadku.
Skúsme si nastaviť kalendár na programátorské vianoce, teda na Halloween (áno, pretože Oct 31 = Dec 25):
V budúcej lekcii, Dátum a čas v Jave 8 - Parsovanie a porovnávanie , sa pozrieme na parsovanie a porovnávanie dátumu a času.