Úvod do rozhrania Java 8 Date / Time API

1. Prehľad

Java 8 predstavila nové API pre Windows Dátum a Čas na riešenie nedostatkov starších java.util.Date a java.util.Calendar.

V rámci tohto článku začnime s problémami v existujúcom Dátum a Kalendár API a poďme diskutovať o tom, ako nová Java 8 Dátum a Čas Riešia ich API.

Pozrime sa tiež na niektoré základné triedy nového projektu Java 8, ktoré sú súčasťou java.time balíček ako LocalDate, LocalTime, LocalDateTime, ZonedDateTime, obdobie, doba trvania a ich podporovaných API.

2. Problémy s existujúcimi Dátum/Čas API

  • Bezpečnosť závitu - Dátum a Kalendár triedy nie sú bezpečné pre vlákna, takže vývojári musia čeliť bolestiam ťažko laditeľných problémov so súbežnosťou a napísať ďalší kód na zvládnutie bezpečnosti vlákien. Naopak nový Dátum a Čas Rozhrania API zavedené v prostredí Java 8 sú nemenné a bezpečné voči vláknam, čo vývojárom odstraňuje túto súbežnú bolesť hlavy.
  • Dizajn API a ľahké porozumenie - Dátum a Kalendár Rozhrania API sú nesprávne navrhnuté s neadekvátnymi metódami na vykonávanie každodenných operácií. Nové Dátum Čas Rozhrania API sú zamerané na ISO a sledujú konzistentné doménové modely pre dátum, čas, trvanie a obdobia. Existuje široká škála užitočných metód, ktoré podporujú najbežnejšie operácie.
  • ZonedDate a Čas - Vývojári museli napísať ďalšiu logiku na spracovanie logiky časovej zóny so starými API, zatiaľ čo s novými API je možné manipuláciu s časovou zónou vykonať pomocou Miestne a ZonedDate/Čas API.

3. Používanie LocalDate, Miestny čas a LocalDateTime

Najčastejšie sa používajú triedy LocalDate, Miestny čas a LocalDateTime. Ako naznačuje ich názov, predstavuje miestny dátum a čas z kontextu pozorovateľa.

Tieto triedy sa používajú hlavne vtedy, keď sa nevyžaduje, aby bola časová zóna výslovne špecifikovaná v kontexte. V rámci tejto časti sa budeme venovať najbežnejšie používaným API.

3.1. Pracujúci s LocalDate

The LocalDate predstavuje dátum vo formáte ISO (rrrr-MM-dd) bez času.

Môže sa použiť na ukladanie dátumov, ako sú narodeniny a výplaty.

Instanciu aktuálneho dátumu je možné vytvoriť zo systémových hodín, ako je uvedené nižšie:

LocalDate localDate = LocalDate.now ();

The LocalDate konkrétny deň, mesiac a rok je možné získať pomocou „z“Alebo použitím metódy„analyzovať”Metóda. Napríklad nasledujúce útržky kódu predstavujú LocalDate do 20. februára 2015:

LocalDate.of (2015, 02, 20); LocalDate.parse ("2015-02-20");

The LocalDate poskytuje rôzne užitočné metódy na získanie rôznych informácií. Poďme sa rýchlo pozrieť na niektoré z týchto metód API.

Nasledujúci úryvok kódu získa aktuálny miestny dátum a pridá jeden deň:

LocalDate tomorrow = LocalDate.now (). PlusDays (1);

Tento príklad získa aktuálny dátum a odpočíta jeden mesiac. Všimnite si, ako prijíma enum ako časová jednotka:

LocalDate previousMonthSameDay = LocalDate.now (). Mínus (1, ChronoUnit.MONTHS);

V nasledujúcich dvoch príkladoch kódu analyzujeme dátum „2016-06-12“ a získame deň v týždni, respektíve deň v mesiaci. Všimnite si návratové hodnoty, prvou je objekt predstavujúci Deň v týždni zatiaľ čo druhý v int predstavujúca radovú hodnotu mesiaca:

DayOfWeek nedeľa = LocalDate.parse ("2016-06-12"). GetDayOfWeek (); int dvanásť = LocalDate.parse ("2016-06-12"). getDayOfMonth ();

Môžeme otestovať, či k dátumu dôjde v priestupnom roku. V tomto príklade testujeme, či je aktuálny dátum priestupný rok:

boolean leapYear = LocalDate.now (). isLeapYear ();

Je možné určiť, že vzťah dátumu k druhému nastane pred alebo po inom dátume:

boolean notBefore = LocalDate.parse ("2016-06-12") .isBefore (LocalDate.parse ("2016-06-11")); boolean isAfter = LocalDate.parse ("2016-06-12") .isAfter (LocalDate.parse ("2016-06-11"));

Hranice dátumu je možné získať od daného dátumu. V nasledujúcich dvoch príkladoch dostaneme LocalDateTime ktorá predstavuje začiatok dňa (2016-06-12T00: 00) daného dátumu a LocalDate čo predstavuje začiatok mesiaca (2016-06-01):

LocalDateTime beginningOfDay = LocalDate.parse ("2016-06-12"). AtStartOfDay (); LocalDate firstDayOfMonth = LocalDate.parse ("2016-06-12") .with (TemporalAdjusters.firstDayOfMonth ());

Poďme sa teraz pozrieť na to, ako pracujeme s miestnym časom.

3.2. Pracujúci s Miestny čas

The Miestny čas predstavuje čas bez dátumu.

Podobný LocalDate inštancia Miestny čas môžu byť vytvorené zo systémových hodín alebo pomocou metódy „parse“ a „of“. Nižšie uvádzam rýchly prehľad niektorých bežne používaných rozhraní API.

Prípad prúdu Miestny čas je možné vytvoriť zo systémových hodín, ako je uvedené nižšie:

LocalTime now = LocalTime.now ();

V nižšie uvedenej ukážke kódu, tvoríme a Miestny čas predstavuje 06:30 dopoludnia analýzou reťazcového vyjadrenia:

LocalTime sixThirty = LocalTime.parse ("06:30");

Továrenskú metódu „of“ možno použiť na vytvorenie a Miestny čas. Napríklad sa vytvorí nasledujúci kód Miestny čas predstavujúce 06:30 dopoludnia pomocou továrenskej metódy:

LocalTime sixThirty = LocalTime.of (6, 30);

Nasledujúci príklad vytvára a Miestny čas syntaktickou analýzou reťazca a pridaním hodiny k nemu pomocou API „plus“. Výsledok by bol Miestny čas predstavujúce 07:30:

LocalTime sevenThirty = LocalTime.parse ("06:30"). Plus (1, ChronoUnit.HOURS);

K dispozícii sú rôzne metódy getra, pomocou ktorých je možné získať konkrétne časové jednotky, ako sú hodiny, minúty a sekundy, ako je uvedené nižšie:

int six = LocalTime.parse ("06:30"). getHour ();

Môžeme tiež skontrolovať, či je konkrétny čas pred alebo po inom konkrétnom čase. Nižšie uvedená ukážka kódu porovnáva dva Miestny čas pre ktorý by bol výsledok pravdivý:

boolean isbefore = LocalTime.parse ("06:30"). isBefore (LocalTime.parse ("07:30"));

Maximálny, minimálny a poludňajší čas dňa možno získať konštantami v Miestny čas trieda. To je veľmi užitočné pri vykonávaní databázových dotazov na vyhľadanie záznamov v danom časovom rozmedzí. Napríklad nasledujúci kód predstavuje 23: 59: 59,99:

LocalTime maxTime = LocalTime.MAX

Teraz sa ponorme LocalDateTime.

3.3. Pracujúci s LocalDateTime

The LocalDateTime sa používa na reprezentáciu kombinácia dátumu a času.

Toto je najbežnejšie používaná trieda, keď potrebujeme kombináciu dátumu a času. Trieda ponúka rôzne API a my sa pozrieme na niektoré z najbežnejšie používaných.

Prípad z LocalDateTime možno získať zo systémových hodín podobne ako LocalDate a Miestny čas:

LocalDateTime.now ();

Nasledujúce ukážky kódu vysvetľujú, ako vytvoriť inštanciu pomocou továrenských metód „of“ a „parse“. Výsledkom by bolo a LocalDateTime inštitút predstavujúci 20. februára 2015, 06:30:

LocalDateTime.of (2015, mesiac.FEBRUARY, 20, 06, 30);
LocalDateTime.parse ("2015-02-20T06: 30: 00");

K dispozícii sú pomocné rozhrania API na podporu sčítania a odčítania konkrétnych časových jednotiek, ako sú dni, mesiace, rok a minúty. Nasledujúce ukážky kódu demonštrujú použitie metód „plus“ a „mínus“. Tieto API sa správajú presne ako ich náprotivky v LocalDate a Miestny čas:

localDateTime.plusDays (1);
localDateTime.minusHours (2);

Na získanie konkrétnych jednotiek podobných triedam dátumu a času sú k dispozícii metódy getera. Vzhľadom na vyššie uvedenú inštanciu LocalDateTime, vzorka kódu uvedená nižšie vráti mesiac február:

localDateTime.getMonth ();

4. Používanie ZonedDateTime API

Java 8 poskytuje ZonedDateTime keď potrebujeme pracovať s konkrétnym dátumom a časom konkrétneho časového pásma. The ZoneId je identifikátor používaný na reprezentáciu rôznych zón. Existuje asi 40 rôznych časových pásiem a ZoneId sa používajú na ich nasledujúcu reprezentáciu.

V tomto útržku kódu vytvoríme Zóna pre Paríž:

ZoneId zoneId = ZoneId.of ("Európa / Paríž"); 

Skupinu všetkých identifikátorov zón nájdete nižšie:

Nastaviť všetkoZoneIds = ZoneId.getAvailableZoneIds ();

The LocalDateTime možno previesť na konkrétnu zónu:

ZonedDateTime zonedDateTime = ZonedDateTime.of (localDateTime, zoneId);

The ZonedDateTime poskytuje analyzovať metóda na získanie konkrétneho dátumu a času podľa časového pásma:

ZonedDateTime.parse ("2015-05-03T10: 15: 30 + 01: 00 [Európa / Paríž]");

Ďalším spôsobom, ako pracovať s časovým pásmom, je použitie OffsetDateTime. The OffsetDateTime je nemenná reprezentácia dátumu a času s posunom. Táto trieda ukladá všetky polia dátumu a času s presnosťou na nanosekundy a tiež s posunom od UTC / Greenwich.

The OffSetDateTime inštanciu je možné vytvoriť nižšie pomocou ZoneOffset. Tu vytvoríme a LocalDateTime 20. februára 2015 o 6:30:

LocalDateTime localDateTime = LocalDateTime.of (2015, Month.FEBRUARY, 20, 06, 30);

Potom k času pripočítame dve hodiny vytvorením a ZoneOffset a nastavenie pre localDateTime inštancia:

ZoneOffset offset = ZoneOffset.of ("+ 02:00"); OffsetDateTime offSetByTwo = OffsetDateTime .of (localDateTime, offset);

Teraz máme localDateTime z 2015-02-20 06:30 +02: 00. Teraz prejdime k tomu, ako upraviť hodnoty dátumu a času pomocou klávesu Obdobie a Trvanie triedy.

5. Používanie Obdobie a Trvanie

The Obdobie trieda predstavuje množstvo času v rokoch, mesiacoch a dňoch a Trvanie trieda predstavuje množstvo času v sekundách a nano sekundách.

5.1. Pracujúci s Obdobie

The Obdobie trieda sa často používa na úpravu hodnôt daného dátumu alebo na získanie rozdielu medzi dvoma dátumami:

LocalDate initialDate = LocalDate.parse ("2007-05-10");

The Dátum je možné manipulovať pomocou Obdobie ako je uvedené v nasledujúcom útržku kódu:

LocalDate finalDate = initialDate.plus (Period.ofDays (5));

The Obdobie trieda má rôzne getrové metódy ako napr getYears, getMonths a getDays získať hodnoty z a Obdobie objekt. Nasledujúci príklad kódu vracia znak int hodnota 5, keď sa snažíme získať rozdiel v dňoch:

int five = Obdobie.medzi (initialDate, finalDate) .getDays ();

The Obdobie medzi dvoma dátumami je možné získať v konkrétnej jednotke, ako sú dni, mesiac alebo roky, pomocou ChronoUnit.b Between:

dlhá päťka = ChronoUnit.DAYS.b Between (initialDate, finalDate);

Tento príklad kódu vráti päť dní. Poďme sa ďalej pozrieť na Trvanie trieda.

5.2. Pracujúci s Trvanie

Podobný Obdobie, the Trieda trvania sa používa na riešenie Čas. V nasledujúcom kóde vytvoríme a Miestny čas o 6:30 a potom pridajte čas 30 sekúnd na vytvorenie a Miestny čas 06:30:30:

LocalTime initialTime = LocalTime.of (6, 30, 0); LocalTime finalTime = initialTime.plus (Duration.ofSeconds (30));

The Trvanie medzi dvoma okamihmi možno získať buď ako a Trvanie alebo ako konkrétna jednotka. V prvom útržku kódu používame znak medzi () metóda Trvanie triedy nájsť časový rozdiel medzi finalTime a initialTime a vrátiť rozdiel v sekundách:

dlhá tridsať = Duration.b Between (initialTime, finalTime) .getSeconds ();

V druhom príklade používame medzi () metóda ChronoUnit triedy na vykonanie tej istej operácie:

dlhá tridsať = ChronoUnit.SECONDS.b Between (initialTime, finalTime);

Teraz sa pozrieme na to, ako previesť existujúce Dátum a Kalendár do nového Dátum/Čas.

6. Kompatibilita s Dátum a Kalendár

Java 8 pridala toInstant () metóda, ktorá pomáha previesť existujúce Dátum a Kalendár inštancia do nového rozhrania API pre čas a čas ako v nasledujúcom útržku kódu:

LocalDateTime.ofInstant (date.toInstant (), ZoneId.systemDefault ()); LocalDateTime.ofInstant (calendar.toInstant (), ZoneId.systemDefault ());

The LocalDateTime je možné zostaviť z epochálnych sekúnd, ako je uvedené nižšie. Výsledkom nižšie uvedeného kódu by bolo a LocalDateTime zastupujúci 2016-06-13T11: 34: 50:

LocalDateTime.ofEpochSecond (1465817690, 0, ZoneOffset.UTC);

Teraz prejdime k Dátum a Čas formátovanie.

7. Dátum a Čas Formátovanie

Java 8 poskytuje API pre ľahké formátovanie Dátum a Čas:

LocalDateTime localDateTime = LocalDateTime.of (2015, mesiac.JANUÁR, 25, 6, 30);

Nasledujúci kód odovzdáva formát dátumu ISO na formátovanie miestneho dátumu. Výsledok bude 2015-01-25:

Reťazec localDateString = localDateTime.format (DateTimeFormatter.ISO_DATE);

The DateTimeFormatter poskytuje rôzne možnosti štandardného formátovania. Tiež je možné poskytnúť vlastné vzory pre metódu formátovania, ako je uvedené nižšie, ktorá by vrátila a LocalDate ako 2015/01/25:

localDateTime.format (DateTimeFormatter.ofPattern ("rrrr / MM / dd"));

Štýl formátovania môžeme odovzdať buď ako KRÁTKY, DLHÉ alebo STREDNÉ ako súčasť možnosti formátovania. Nižšie uvedená ukážka kódu poskytne výstup predstavujúci LocalDateTime 25. januára 2015, 06:30:00:

localDateTime .format (DateTimeFormatter.ofLocalizedDateTime (FormatStyle.MEDIUM)). sLocale (Locale.UK);

Pozrime sa na alternatívy dostupné pre Java 8 Core Dátum/Čas API.

8. Backport a alternatívne možnosti

8.1. Používanie Project Threeten

Pre organizácie, ktoré sú na ceste k prechodu na Javu 8 z Javy 7 alebo Javy 6 a chcú používať API pre dátum a čas, poskytuje projekt back-end možnosť tri. Vývojári môžu pomocou tried dostupných v tomto projekte dosiahnuť rovnakú funkcionalitu ako v novom prostredí Java 8 Dátum a Čas API a po prechode na Javu 8 je možné balíčky prepínať. Artefakt pre projekt threeten nájdete v centrálnom úložisku maven:

 org.threeten threetenbp 1.3.1 

8.2. Knižnica Joda-Time

Ďalšia alternatíva pre Java 8 Dátum a Čas knižnica je knižnica Joda-Time. V skutočnosti Java 8 Dátum Čas API spoločne viedli autor knižnice Joda-Time (Stephen Colebourne) a Oracle. Táto knižnica poskytuje takmer všetky funkcie podporované v prostredí Java 8 Dátum Čas projekt. Artefakt nájdete v centrálnej časti súboru zahrnutím závislosti závislostí pod vaším projektom:

 joda-time joda-time 2.9.4 

9. Záver

Java 8 poskytuje bohatú sadu API s konzistentným dizajnom API pre ľahší vývoj.

Ukážky kódu pre vyššie uvedený článok nájdete v repozitári Java 8 Date / Time git.