Migrácia na nové rozhranie Java 8 Date Time API

1. Prehľad

V tomto tutoriáli sa dozviete, ako refaktorovať váš kód, aby ste využili nové rozhranie Date Time API zavedené v prostredí Java 8.

2. Nové API v skratke

Práca s dátumami v Jave bývala ťažká. Stará knižnica dátumov poskytovaná JDK obsahovala iba tri triedy: java.util.Date, java.util.Calendar a java.util.Timezone.

Boli vhodné iba na najzákladnejšie úlohy. Pre všetko, čo je aj vzdialene zložité, museli vývojári použiť buď knižnice tretích strán, alebo napísať kopu vlastného kódu.

Java 8 predstavila úplne nové rozhranie Date Time API (java.util.time. *), ktorý je voľne založený na populárnej knižnici Java s názvom JodaTime. Toto nové API dramaticky zjednodušilo spracovanie dátumu a času a opravilo veľa nedostatkov starej knižnice dátumov.

1.1. Zrozumiteľnosť API

Prvá výhoda nového API je jasnosť - API je veľmi jasné, stručné a ľahko pochopiteľné. Neobsahuje veľa nezrovnalostí v starej knižnici, napríklad číslovanie polí (v Kalendári sú mesiace založené na nule, ale dni v týždni sú založené na jednom).

1.2. Flexibilita API

Ďalšou výhodou je flexibilita - práca s viacerými reprezentáciami času. Stará knižnica dátumov obsahovala iba jednu triedu reprezentácie času - java.util.Date, ktorý je napriek svojmu názvu v skutočnosti časovou značkou. Ukladá iba počet milisekúnd, ktoré uplynuli od epochy Unixu.

Nové API má veľa rôznych časových reprezentácií, z ktorých každá je vhodná pre rôzne prípady použitia:

  • Okamžité - predstavuje časový bod (časová značka)
  • LocalDate - predstavuje dátum (rok, mesiac, deň)
  • LocalDateTime - rovnaké ako LocalDate, ale zahŕňa čas s presnosťou na nanosekundy
  • OffsetDateTime - rovnaké ako LocalDateTime, ale s posunom časového pásma
  • Miestny čas - čas s presnosťou na nanosekundy a bez informácií o dátume
  • ZonedDateTime - rovnaké ako OffsetDateTime, ale obsahuje ID časového pásma
  • OffsetLocalTime - rovnaké ako Miestny čas, ale s posunom časového pásma
  • MonthDay - mesiac a deň, bez roku alebo času
  • RokMesiac - mesiac a rok bez dňa alebo času
  • Trvanie - množstvo času vyjadrené v sekundách, minútach a hodinách. Má presnosť nanosekúnd
  • Obdobie - množstvo času vyjadrené v dňoch, mesiacoch a rokoch

1.3. Nezmeniteľnosť a bezpečnosť závitov

Ďalšou výhodou je, že všetky časové reprezentácie v rozhraní Java 8 Date Time API sú nemenné a teda bezpečné pre vlákna.

Všetky mutujúce metódy vrátia novú kópiu namiesto úpravy stavu pôvodného objektu.

Staré triedy ako napr java.util.Date neboli bezpečné pre vlákna a mohli by zaviesť veľmi jemné chyby súbežnosti.

1.4. Metóda reťazenia

Všetky metódy mutácie je možné spojiť dohromady, čo umožňuje implementovať komplexné transformácie v jednom riadku kódu.

ZonedDateTime nextFriday = LocalDateTime.now () .plusHours (1) .with (TemporalAdjusters.next (DayOfWeek.FRIDAY)) .atZone (ZoneId.of ("PST")); 

2. Príklady

Nasledujúce príklady ukážu, ako vykonávať bežné úlohy so starým aj novým API.

Získava sa aktuálny čas

// Teraz starý dátum = nový dátum (); // Nový ZonedDateTime now = ZonedDateTime.now (); 

Predstavuje konkrétny čas

// Starý dátum birthDay = nový GregorianCalendar (1990, Calendar.DECEMBER, 15) .getTime (); // Nové LocalDate birthDay = LocalDate.of (1990, Month.DECEMBER, 15); 

Extrahovanie konkrétnych polí

// Starý int mesiac = nový GregorianCalendar (). Get (Calendar.MONTH); // Nový mesiac mesiac = LocalDateTime.now (). GetMonth (); 

Sčítanie a odčítanie času

// Starý kalendár GregorianCalendar = nový GregorianCalendar (); calendar.add (Calendar.HOUR_OF_DAY, -5); Dátum fiveHoursBefore = calendar.getTime (); // Nový LocalDateTime fiveHoursBefore = LocalDateTime.now (). MinusHours (5); 

Zmena konkrétnych polí

// Starý kalendár GregorianCalendar = nový GregorianCalendar (); calendar.set (Calendar.MONTH, Calendar.JUNE); Dátum inJune = calendar.getTime (); // Nový LocalDateTime inJune = LocalDateTime.now (). WithMonth (Month.JUNE.getValue ()); 

Orezávanie

Skrátením sa resetujú všetky časové polia menšie ako zadané pole. V príklade uvedenom nižšie budú všetky minúty nižšie a nastavia sa na nulu

// Starý kalendár teraz = Calendar.getInstance (); now.set (Calendar.MINUTE, 0); now.set (Calendar.SECOND, 0); now.set (Calendar.MILLISECOND, 0); Dátum skrátený = now.getTime (); // Nový LocalTime truncated = LocalTime.now (). TruncatedTo (ChronoUnit.HOURS); 

Prepočet časového pásma

// Starý kalendár GregorianCalendar = nový GregorianCalendar (); calendar.setTimeZone (TimeZone.getTimeZone ("CET")); Dátum centralEastern = calendar.getTime (); // Nový ZonedDateTime centralEastern = LocalDateTime.now (). AtZone (ZoneId.of ("CET")); 

Získanie časového rozpätia medzi dvoma časovými bodmi

// Starý kalendár GregorianCalendar = nový GregorianCalendar (); Dátum teraz = nový Dátum (); calendar.add (Calendar.HOUR, 1); Dátum hourLater = calendar.getTime (); dlho uplynul = hourLater.getTime () - teraz.getTime (); // Nový LocalDateTime now = LocalDateTime.now (); LocalDateTime hourLater = LocalDateTime.now (). PlusHours (1); Duration span = Duration.b Between (now, hourLater); 

Formátovanie a analýza času

DateTimeFormatter je náhrada za starý SimpleDateFormat, ktorý je bezpečný pre vlákna a poskytuje ďalšie funkcie.

// Starý SimpleDateFormat dateFormat = nový SimpleDateFormat ("rrrr-MM-dd"); Dátum teraz = nový Dátum (); Reťazec formattedDate = dateFormat.format (teraz); Dátum parsedDate = dateFormat.parse (formattedDate); // Nový LocalDate now = LocalDate.now (); DateTimeFormatter formatter = DateTimeFormatter.ofPattern ("rrrr-MM-dd"); Reťazec formattedDate = now.format (formatter); LocalDate parsedDate = LocalDate.parse (formattedDate, formatter); 

Počet dní v mesiaci

// Starý kalendár kalendára = nový GregorianCalendar (1990, Calendar.FEBRUARY, 20); int daysInMonth = calendar.getActualMaximum (Calendar.DAY_OF_MONTH); // New int daysInMonth = YearMonth.of (1990, 2) .lengthOfMonth ();

3. Interakcia so starým kódom

V mnohých prípadoch môže byť potrebné, aby používateľ zabezpečil interoperabilitu s knižnicami tretích strán, ktoré sa spoliehajú na starú knižnicu dátumov.

V Jave 8 boli staré triedy knižníc dátumov rozšírené o metódy, ktoré ich prevádzajú na zodpovedajúce objekty z nového rozhrania Date API.

Nové triedy poskytujú podobné funkcie.

Okamžité instantFromCalendar = GregorianCalendar.getInstance (). ToInstant (); ZonedDateTime zonedDateTimeFromCalendar = nový GregorianCalendar (). ToZonedDateTime (); Dátum dateFromInstant = Date.from (Instant.now ()); GregorianCalendar calendarFromZonedDateTime = GregorianCalendar.from (ZonedDateTime.now ()); Okamžité instantFromDate = nový dátum (). ToInstant (); ZoneId zoneIdFromTimeZone = TimeZone.getTimeZone ("PST"). ToZoneId (); 

4. Záver

V tomto článku sme preskúmali nové rozhranie Date Time API dostupné v prostredí Java 8. Pozreli sme sa na jeho výhody v porovnaní so zastaraným API a na niekoľko príkladov sme poukázali na rozdiely.

Upozorňujeme, že sme sotva poškriabali povrch schopností nového rozhrania Date Time API. Prečítajte si oficiálnu dokumentáciu a objavte celú škálu nástrojov, ktoré ponúka nové API.

Príklady kódov nájdete v projekte GitHub.


$config[zx-auto] not found$config[zx-overlay] not found