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ő: 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: 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: Á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: Vizsgáljuk meg a Java 8 Core elérhető alternatíváit Dátum/Idő API-k. 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ó: 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: 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.LocalDateTime localDateTime = LocalDateTime.of (2015, Month.JANUARY, 25, 6, 30);
String localDateString = localDateTime.format (DateTimeFormatter.ISO_DATE);
localDateTime.format (DateTimeFormatter.ofPattern ("éééé / HH / NN"));
localDateTime .format (DateTimeFormatter.ofLocalizedDateTime (FormatStyle.MEDIUM)) .withLocale (Locale.UK);
8. Hátlap és alternatív opciók
8.1. A Project Threeten használata
org.threeten threetenbp 1.3.1
8.2. Joda-Time könyvtár
joda-idő joda-idő 2.9.4
9. Következtetés