Adaptace nových verzí Javy jde pomalu. Dodnes vídám, že programátoři neumí či nechtějí používat multi catch, try-with-resources a diamond operátor. Jak chtít složitější posun, který přináší Java 8?

Ovšem sám nejsem bez viny. Java 8 už je tu víc jak dva roky. Při jejím uvedení jsem psal, jak obstojí v Akumulátor testu, ale na projek­tech ji naplno nevyužíváme. Rozhodl jsem se to napravit tím, že začnu používat java.time.* místo java.util.Date. Jednak kvůli API a taky proto, že jsou nové třídy immutable. Chtěl bych se podělit o to, jak jsem se při tom nachy­tal.

java.timex

V příkla­dech testování a mockování času je uvedená třída Instant, ale potře­boval jsem převod do LocalTime. Jakožto empirický programátor (to jest zkouším, co mi nadhodí kontex­tová nápověda) píšu:

LocalTime.from(Instant.now())

Jenže ouha

java.time.DateTimeException: Unable to obtain LocalTime from TemporalAccessor:
2016-08-22T20:40:05.875Z of type java.time.Instant

Našel jsem vysvět­lení na Stack Overflow. Doporučuji k přečtení celé, ale přináším alespoň výtah.

Autoři speci­fi­kace JSR-310 nechtěli, aby lidé převáděli mezi strojovým a lidským časem přes statické metody from() v typech jako ZoneId, ZoneOff­set, OffsetDa­te­Time, ZonedDa­te­Time atd. Pokud byste pečlivě studo­vali javadoc, je to tam výslovně speci­fi­ko­vané. Místo toho použijte:

OffsetDateTime#toInstant():Instant
ZonedDateTime#toInstant():Instant
Instant#atOffset(ZoneOffset):OffsetDateTime
Instant#atZone(ZoneId):ZonedDateTime

Problém se static­kými metodami from() je v tom, že jinak jsou lidé schopní převádět mezi Instant a například Local­Da­te­Time, aniž by přemýšleli o časové zóně.

Všechny statické metody from() jsou až příliš veřejné. Podle mého názoru jsou příliš snadno přístupné a měly by být raději odstraněny z veřej­ného API nebo by měly používat speci­fič­tější parametr než Tempo­ra­lAccessor. Slabou stránkou těchto metod je to, že lidé můžou při konverzi zapome­nout na souvi­sející časovou zónu, protože začnou dotaz s lokálním typem. Zvažte napřík­lad: Local­Da­te.from(a­nIn­stant) (v jaké časové zóně???)

Testování

Nebudu vás víc napínat teorií. Zde je příklad, kdy konfi­gu­race je interval v hodinách (od do), přičemž na serveru běží strojový čas. Součástí příkladu je i test v Groovy.

Bean Validation

Závěrem ještě jeden zásek, proč je přechod na java.ti­me.* složitější, a tím je chybějící podpora v Bean Valida­tion. Jistě, můžete si validátory napsat sami, ale v Hiber­nate nejsou. Issue HHH-8844 se sice vztahuje k hibernate-core, ale může vysvětlit i validátor. Prostě drží zpětnou kompa­ti­bi­litu k Javě 6. Ovšem svítá naděje v podobě Bean Valida­tion 2.0