IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

12. diel - Dátum a čas v Kotlin - Úprava a intervaly

V minulej lekcii, Dátum a čas v Kotlin - Vytváranie a formátovanie , sme sa naučili vytvárať inštancie LocalDate, LocalTime a LocalDateTime a formátovať ich hodnotu. V dnešnom Kotlin tutoriálu sa budeme venovať úprave tejto hodnoty a zabehneme aj do časových intervalov.

Prevody

Na úvod si ukážme, ako môžeme prevádzať medzi LocalDate, LocalTime a LocalDateTime.

Prevod z LocalDateTime

Z LocalDateTime prevádzame jednoducho pomocou jeho metód toLocalDate() a toLocalTime().

Prevod na LocalDateTime

LocalDateTime vytvoríme pomocou jednej z of*() metód, kde uvedieme zvlášť dátum a čas, napr. Takto:

val zacatek = LocalDate.of(1939, 9, 1)
val datumCas = LocalDateTime.of(zacatek, LocalTime.of(10, 0))

Ak chceme nastaviť čas na začiatok dňa, môžeme využiť metódy atStartOfDay(). Ďalšou metódou, ktorú môžeme vziať dátum a pripojiť k nemu čas, je atTime(). Ďalšie variant príkladu vyššie by teda bola:

val zacatek = LocalDate.of(1939, 9, 1)
val datumCas = zacatek.atStartOfDay()
val datumCas2 = zacatek.atTime(0, 0)

Úprava hodnoty

K existujúcej inštanciu môžeme pripísať určitý počet dní, hodín a podobne. Slúži 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 Kotlinu s textovými reťazcami).

Skúsme si to a pridajme aktuálnemu dátumu ďalšie 3 dni v týždni:

var datumCas = LocalDateTime.now()
datumCas = datumCas.plusDays(3)
println(datumCas.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)))

výsledok:

9.1.2017

Metódy, ktoré máme k dispozícii, sú nasledujúce:

  • minusDays()
  • minusHours()
  • minusMinutes()
  • minusMonths()
  • minusNanos()
  • minusSeconds()
  • minusWeeks()
  • minusYears()
  • plusDays()
  • plusHours()
  • plusMinutes()
  • plusMonths()
  • plusNanos()
  • plusSeconds()
  • plusWeeks()
  • plusYears()

Period a Duration

Okrem vyššie spomenutých metód nájdeme aj 4 všeobecnej verzie metód minus() a plus(), ktoré prijímajú interval na pridanie / odobratie. Využijeme je najmä v prípade, keď dopredu nevieme, či budeme pridávať napr. Dni alebo roky, ušetrí nám veľa podmínkování. Máme k dispozícii triedy Duration a Period, na ktorých si môžeme nechať vrátiť objekt reprezentujúci taký interval.

Až sa dostaneme k rozhraním, môžete sa pozrieť, že obe triedy implementujúce spoločné rozhranie TemporalAmount. Zatiaľ si s nimi však nemotejme hlavu.

Upravený kód nášho príkladu by vyzeral takto:

var datumCas = LocalDateTime.now()
datumCas = datumCas.plus(Period.ofDays(3))
println(datumCas.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)))

Pretože nám Kotlin umožňuje tzv. Preťažovanie operátorov, viac ďalej v kurze, môžeme kód vyššie zapísať aj týmto spôsobom:

var datumCas = LocalDateTime.now()
datumCas += Period.ofDays(3)
println(datumCas.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)))

Výstup bude rovnaký, ako v príklade vyššie. Of...*() metódy majú rovnaké "prípony" ako mali plus / mínus metódy uvedené vyššie.

Rozdiel medzi Period a Duration je ten, že Duration 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. 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 LocalDate / LocalDateTime, Duration pri práci s časom.

ChronoUnit

Pre ľahšie 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, jedná sa teda iba o iný zápis už predchádzajúcich úloh, ale len pre istotu, keby ste ho niekedy stretli, ukážme si ho:

var datumCas = LocalDateTime.now()
datumCas = datumCas.plus(3, ChronoUnit.DAYS)
println(datumCas.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)))

Len pre úplnosť si dodajme, že ChronoUnit implementuje rozhranie TemporalUnit, keby ste sa s ním neskôr stretli. Teraz rozhranie riešiť nebudeme.

Ako vidíte, implementácia dátumu a času je v Kotlinu pomerne zložitá, nebudeme tu zabiehať do zbytočných detailov a zameriame sa najmä na praktickú stránku použitia, ako to na ITnetwork väčšinou robíme.

Between ()

Ako posledný stojí za zmienku statická metóda between() na triede Period, ktorá nám umožňuje získať interval, teda rozdiel medzi 2 dátumy (presnejšie objekty s rozhraním Temporal, to je spoločný typ pre LocalDate, LocalDateTime a LocalTime). Zámerne tu nebudem písať češtinsky správne "medzi dvoma dátumami", pretože je to v IT zavádzajúce slovo.

val zacatek = LocalDate.of(1939, 9, 1)
val konec = LocalDate.of(1945, 9, 2)
val doba = Period.between(zacatek, konec)
println("II. světová válka trvala " + doba.get(ChronoUnit.YEARS) + " let a " + doba.get(ChronoUnit.DAYS) + " dní")

Tú istú metódu nájdeme aj na triede Duration, ktorá však pracuje s LocalDateTime miesto s LocalDate. Z intervale 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.

Nastavenie hodnoty

Hodnotu nastavujeme pomocou metód with...*(), majú opäť tie isté "prípony" ako metódy doteraz spomínané. Ako vždy nezabudnite, že ako všetky podobné metódy vracajú novú inštanciu.

var zacatek = LocalDate.of(1939, 9, 1)
zacatek = zacatek.withYear(1945) // Nastaví rok na 1945

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 31 OCT = 25 DEC).

var zacatek = LocalDate.of(1939, 9, 1)
zacatek = zacatek.withMonth(9).withDayOfMonth(31)

V budúcej lekcii, Dátum a čas v Kotlin - parsovanie a porovnávanie , budeme pokračovať a dátum a čas v Kotlinu dokončíme. Ukážeme si ako hodnoty čítať a ako dátum a čas v Kotlinu parsovať.


 

Predchádzajúci článok
Dátum a čas v Kotlin - Vytváranie a formátovanie
Všetky články v sekcii
Objektovo orientované programovanie v Kotlin
Preskočiť článok
(neodporúčame)
Dátum a čas v Kotlin - parsovanie a porovnávanie
Článok pre vás napísal Samuel Kodytek
Avatar
Užívateľské hodnotenie:
1 hlasov
Autor se věnuje všem jazykům okolo JVM. Rád pomáhá lidem, kteří se zajímají o programování. Věří, že všichni mají šanci se naučit programovat, jen je potřeba prorazit tu bariéru, který se říká lenost.
Aktivity