Bevezetés a Java 8 dátum / idő API-ba

1. Áttekintés

A Java 8 új API-kat vezetett be a Dátum és Idő az idősebbek hiányosságainak orvoslására java.util.Dátum és java.util.Naptár.

E cikk részeként kezdjük a meglévő kérdésekkel Dátum és Naptár API-k, és beszéljük meg, hogyan működik az új Java 8 Dátum és Idő Az API-k megszólítják őket.

Megvizsgáljuk az új Java 8 projekt néhány alapvető osztályát is, amelyek a java.time csomag, mint LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Period, Duration és az általuk támogatott API-k.

2. A meglévő kérdések Dátum/Idő API-k

  • Menetbiztonság - A Dátum és Naptár osztályok nem biztonságosak a szálakban, így a fejlesztők feladata a nehezen debugálható egyidejűségi problémák fejfájása, és további kódok írása a szálbiztonság kezelésére. Épp ellenkezőleg az új Dátum és Idő A Java 8-ban bevezetett API-k változhatatlanok és szálbiztonságosak, így elveszik ezt a párhuzamossági fejfájást a fejlesztőktől.
  • API-k tervezése és az egyszerű megértés - A Dátum és Naptár Az API-k rosszul vannak kialakítva, nem megfelelő módszerekkel a mindennapi műveletek végrehajtására. Az új Dátum idő Az API-k ISO-központúak és következetes tartománymodelleket követnek a dátum, az idő, az időtartam és az időszakok szerint. A legáltalánosabb műveleteket támogató segédprogramok széles skálája létezik.
  • ZonedDate és Idő - A fejlesztőknek további logikát kellett írniuk, hogy kezeljék az időzóna logikáját a régi API-kkal, míg az új API-kkal az időzóna kezelése Helyi és ZonedDate/Idő API-k.

3. Használata LocalDate, Helyi idő és LocalDateTime

A leggyakrabban használt osztályok LocalDate, Helyi idő és LocalDateTime. Ahogy a nevük is jelzi, a helyi Dátum / Időt képviselik a megfigyelő kontextusából.

Ezeket az osztályokat főleg akkor használják, ha az időzónát nem kell kifejezetten megadni a kontextusban. E szakasz részeként a leggyakrabban használt API-kat tárgyaljuk.

3.1. Dolgozni vele LocalDate

A LocalDate képviseli dátum ISO formátumban (éééé-hh-nn), idő nélkül.

Használható dátumok, például születésnapok és fizetésnapok tárolására.

Az aktuális dátum példánya létrehozható a rendszer órájáról az alábbiak szerint:

LocalDate localDate = LocalDate.now ();

A LocalDate egy adott napot, hónapot és évet a „nak,-nek”Módszerrel vagy a„elemzés”Módszer. Például az alábbi kódrészletek a LocalDate 2015. február 20-ig:

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

A LocalDate különféle hasznos módszereket biztosít a különféle információk megszerzéséhez. Nézzünk meg néhányat ezekről az API-król.

A következő kódrészlet megkapja az aktuális helyi dátumot, és hozzáad egy napot:

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

Ez a példa megkapja az aktuális dátumot, és kivon egy hónapot. Vegye figyelembe, hogyan fogadja el az enum mint időegység:

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

A következő két kódpéldában elemezzük a „2016-06-12” dátumot, és megkapjuk a hét napját, illetve a hónap napját. Vegye figyelembe a visszatérési értékeket, az első egy objektum, amely a A hét napja míg a második egy int a hónap sorszámát képviseli:

DayOfWeek vasárnap = LocalDate.parse ("2016-06-12"). GetDayOfWeek (); int tizenkettő = LocalDate.parse ("2016-06-12"). getDayOfMonth ();

Kipróbálhatjuk, hogy a dátum szökőévben történik-e. Ebben a példában azt teszteljük, hogy az aktuális dátum szökőév-e:

logikai ugrásYear = LocalDate.now (). isLeapYear ();

Megállapítható, hogy a dátum viszonya egy másik dátum előtt vagy után következik be:

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

A dátumhatárokat egy adott dátumtól lehet beszerezni. A következő két példában megkapjuk a LocalDateTime ami az adott dátum napjának (2016-06-12T00: 00) kezdetét jelenti, és a LocalDate amely a hónap elejét (2016-06-01) jelenti:

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

Most nézzük meg, hogyan működünk a helyi idővel.

3.2. Dolgozni vele Helyi idő

A Helyi idő képviseli dátum nélküli idő.

Hasonló LocalDate példánya Helyi idő létrehozható a rendszer órájából vagy a „parse” és a „of” módszer használatával. Gyors áttekintés az alábbiakban ismertetett néhány gyakran használt API-ról.

Az áram példánya Helyi idő a rendszeróráról az alábbiak szerint hozható létre:

LocalTime now = LocalTime.now ();

Az alábbi kódmintában, létrehozunk egy Helyi idő 06: 30-at ábrázol egy karakterlánc-ábrázolás elemzésével:

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

A „of” gyári módszere felhasználható a Helyi idő. Például az alábbi kód létrehoz Helyi idő ami 06: 30-kor repül gyári módszerrel:

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

Az alábbi példa létrehozza a Helyi idő egy sztring elemzésével, és hozzáad egy órát a „plus” API használatával. Az eredmény az lenne Helyi idő képviselő: 07:30:

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

Különböző getter módszerek állnak rendelkezésre, amelyek felhasználásával meghatározott időegységeket, például órát, percet és másodperceket kaphatnak, például az alábbiak szerint:

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

Azt is ellenőrizhetjük, hogy egy adott idő egy másik meghatározott idő előtt vagy után van-e. Az alábbi kódminta kettőt hasonlít össze Helyi idő amelyre az eredmény igaz lenne:

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

A napi max, min és déli időpontot a konstansok megadhatják Helyi idő osztály. Ez nagyon hasznos, ha adatbázis-lekérdezéseket hajt végre rekordok megkeresésére egy adott időtartamon belül. Például az alábbi kód 23: 59: 59.99:

LocalTime maxTime = LocalTime.MAX

Most merüljünk el LocalDateTime.

3.3. Dolgozni vele LocalDateTime

A LocalDateTime ábrázolására használják dátum és idő kombinációja.

Ez a leggyakrabban használt osztály, amikor dátum és idő kombinációjára van szükségünk. Az osztály számos API-t kínál, és megnézzük a leggyakrabban használtakat.

Példája LocalDateTime -hez hasonló rendszerórából szerezhető be LocalDate és Helyi idő:

LocalDateTime.now ();

Az alábbi kódminták elmagyarázzák, hogyan lehet létrehozni egy példányt a gyári „of” és „parse” módszerekkel. Az eredmény a LocalDateTime 2015. február 20-án, 06:30 órakor képviselő bíróság:

LocalDateTime.of (2015, hónap. FEBRUÁR, 20., 06., 30.);
LocalDateTime.parse ("2015-02-20T06: 30: 00");

Vannak segédprogram API-k, amelyek támogatják az egyes időegységek összeadását és kivonását, például a napok, hónapok, év és perc rendelkezésre állnak. Az alábbi kódminták a „plusz” és a „mínusz” módszer használatát mutatják be. Ezek az API-k pontosan úgy viselkednek, mint társaik LocalDate és Helyi idő:

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

Getter módszerek állnak rendelkezésre a dátum és idő osztályokhoz hasonló meghatározott egységek kinyerésére. Tekintettel a fenti LocalDateTime, az alábbi kódminta a február hónapot adja vissza:

localDateTime.getMonth ();

4. Használata ZonedDateTime API

A Java 8 biztosítja ZonedDateTime amikor az időzóna-specifikus dátummal és idővel kell foglalkoznunk. A ZoneId egy azonosító, amelyet a különböző zónák képviseletére használnak. Körülbelül 40 különböző időzóna van, és a ZoneId ábrázolásukra az alábbiak szerint kerül sor.

Ebben a kódrészletben létrehozunk egy Zóna Párizs esetében:

ZoneId zoneId = ZoneId.of ("Európa / Párizs"); 

Az összes zónaazonosító készlet az alábbiak szerint szerezhető be:

Set allZoneIds = ZoneId.getAvailableZoneIds ();

A LocalDateTime átalakítható egy meghatározott zónává:

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

A ZonedDateTime biztosítja elemzés módszer az időzóna-specifikus dátum és idő megszerzésére:

ZonedDateTime.parse ("2015-05-03T10: 15: 30 + 01: 00 [Európa / Párizs]";

Az időzónával való munka másik módja a OffsetDateTime. A OffsetDateTime a dátum-idő eltolhatatlan ábrázolása. Ez az osztály tárolja az összes dátum- és időmezőt, nanoszekundum pontossággal, valamint az UTC / Greenwich eltolását.

A OffSetDateTime példány az alábbiak szerint hozható létre a ZoneOffset. Itt létrehozunk egy LocalDateTime 2015. február 20-án reggel 6: 30-kor:

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

Ezután hozzáadunk két órát az időhöz a létrehozásával ZoneOffset és a localDateTime példa:

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

Most van egy localDateTime 2015-02-20 06:30 +02: 00. Most térjünk át arra, hogyan lehet módosítani a dátum- és időértékeket a Időszak és Időtartam osztályok.

5. Használata Időszak és Időtartam

A Időszak osztály egy időmennyiséget jelent év, hónap és nap, valamint a Időtartam osztály az idő mennyiségét jelenti másodpercekben és nano másodpercekben kifejezve.

5.1. Dolgozni vele Időszak

A Időszak osztályt széles körben használják az adott dátum értékeinek módosítására vagy a két dátum közötti különbség megszerzésére:

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

A Dátum segítségével manipulálható Időszak a következő kódrészletben látható módon:

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

A Időszak osztály különböző getter módszerekkel rendelkezik, mint pl getYears, getMonths és getDays hogy értékeket kapjon a Időszak tárgy. Az alábbi kódpélda egy int értéke 5, miközben megpróbálunk különbséget tenni a napok szempontjából:

int öt = Period.between (initialDate, finalDate) .getDays ();

A Időszak két dátum között lehet megadni egy adott egységben, például napokban, hónapokban vagy években ChronoUnit. között:

hosszú öt = ChronoUnit.DAYS.between (kezdőDátum, végsőDátum);

Ez a kódpélda öt napot ad vissza. Folytassuk egy pillantással a Időtartam osztály.

5.2. Dolgozni vele Időtartam

Hasonló Időszak, a Időtartam osztály kezelésére szolgál Idő. A következő kódban létrehozunk egy Helyi idő 6: 30-kor, majd adjon hozzá egy 30 másodperces időtartamot a Helyi idő 06:30:30 órától:

LocalTime initialTime = LocalTime.of (6, 30, 0); LocalTime finalTime = initialTime.plus (másodpercek időtartama (30));

A Időtartam két pillanat között vagy a Időtartam vagy meghatározott egységként. Az első kódrészletben a között() módszere Időtartam osztályban megtalálni az időeltolódást finalTime és initialTime és adja meg a különbséget másodpercben:

long harminc = Duration.between (initialTime, finalTime) .getSeconds ();

A második példában a között() módszere ChronoUnit osztály ugyanazon művelet végrehajtására:

hosszú harminc = ChronoUnit.SECONDS.between (kezdeti idő, végső idő);

Most megnézzük, hogyan lehet átalakítani a meglévőket Dátum és Naptár újra Dátum/Idő.

6. Kompatibilitás Dátum és Naptár

A Java 8 hozzáadta a azonnali () módszer, amely segíti a meglévő átalakítását Dátum és Naptár példányt az új dátum és idő API-hoz, a következő kódrészletben:

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

A LocalDateTime korszakokból készíthető, az alábbiak szerint. Az alábbi kód eredménye a LocalDateTime képviselő 2016-06-13T11: 34: 50:

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

Most térjünk rá Dátum és Idő formázás.

7. Dátum és Idő Formázás

A Java 8 API-kat biztosít az egyszerű formázáshoz Dátum és Idő:

LocalDateTime localDateTime = LocalDateTime.of (2015, Month.JANUARY, 25, 6, 30);

Az alábbi kód ISO dátumformátumot ad át a helyi dátum formázásához. Az eredmény 2015-01-25 lenne:

String localDateString = localDateTime.format (DateTimeFormatter.ISO_DATE);

A DateTimeFormatter különféle formázási opciókat biztosít. Az egyedi minták megadhatók a formázási módszerhez is, az alábbihoz hasonlóan, amelyek a LocalDate mint 2015/01/25:

localDateTime.format (DateTimeFormatter.ofPattern ("éééé / HH / NN"));

Átadhatunk formázási stílusban akár as RÖVID, HOSSZÚ vagy KÖZEPES a formázási opció részeként. Az alábbi kódminta egy kimenetet képvisel LocalDateTime 2015. január 25-én, 06:30:00 órakor:

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

Vizsgáljuk meg a Java 8 Core elérhető alternatíváit Dátum/Idő API-k.

8. Hátlap és alternatív opciók

8.1. A Project Threeten használata

Azoknál a szervezeteknél, amelyek a Java 8-ra való áttérés útján állnak a Java 7-ből vagy a Java 6-ból, és szeretnék használni a dátum és idő API-t, a project threeten biztosítja a backport képességet. A fejlesztők a projektben elérhető osztályokat használhatják az új Java 8-hoz hasonló funkcionalitás elérésére Dátum és Idő API és miután áttérnek a Java 8-ra, a csomagok átállíthatók. A threeten projekt tárgya a maven központi adattárban található:

 org.threeten threetenbp 1.3.1 

8.2. Joda-Time könyvtár

A Java 8 másik alternatívája Dátum és Idő a Joda-Time könyvtár. Valójában a Java 8 Dátum idő Az API-kat a Joda-Time könyvtár szerzője (Stephen Colebourne) és az Oracle közösen vezette. Ez a könyvtár nagyjából minden olyan képességet biztosít, amelyet a Java 8 támogat Dátum idő projekt. Az Artefact megtalálható a maven centralban, azáltal, hogy a projektbe belefoglalja az alábbi pom függőséget:

 joda-idő joda-idő 2.9.4 

9. Következtetés

A Java 8 gazdag API-kat kínál, következetes API-tervezéssel a könnyebb fejlesztés érdekében.

A fenti cikk kódmintái megtalálhatók a Java 8 Date / Time git repository-ban.