Uvod u API za datum / vrijeme Java 8

1. Pregled

Java 8 predstavila je nove API-je za Datum i Vrijeme rješavati nedostatke starijih java.util.Datum i java.util.Kalendar.

Kao dio ovog članka, krenimo s postojećim problemima Datum i Kalendar API-ji i razgovarajmo o tome kako nova Java 8 Datum i Vrijeme API-ji im se obraćaju.

Također ćemo razmotriti neke od temeljnih klasa novog projekta Java 8 koji su dio java.vrijeme paket poput LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Period, Duration i njihovi podržani API-ji.

2. Problemi sa postojećim Datum/Vrijeme Apis

  • Sigurnost navoja - The Datum i Kalendar klase nisu zaštićene od niti, ostavljajući programerima da se nose s glavoboljom problema s istodobnošću koji se teško rješavaju i napišu dodatni kôd za upravljanje sigurnošću niti. Naprotiv novo Datum i Vrijeme API-ji uvedeni u Javi 8 nepromjenjivi su i sigurni u nitima, tako da programerima uklanjaju tu glavobolju istodobnosti.
  • Dizajn API-ja i jednostavnost razumijevanja - The Datum i Kalendar API-ji su loše dizajnirani s neadekvatnim metodama za obavljanje svakodnevnih operacija. Novi Datum vrijeme API je usmjeren na ISO i slijedi dosljedne modele domena za datum, vrijeme, trajanje i razdoblja. Postoji širok spektar korisnih metoda koje podržavaju najčešće operacije.
  • ZonedDate i Vrijeme - Programeri su morali napisati dodatnu logiku za rukovanje logikom vremenske zone sa starim API-ima, dok se s novim API-ima rukovanje vremenskom zonom može izvršiti Lokalno i ZonedDate/Vrijeme Apis.

3. Korištenje LocalDate, Lokalno vrijeme i LocalDateTime

Najčešće korištene klase su LocalDate, Lokalno vrijeme i LocalDateTime. Kao što njihova imena pokazuju, oni predstavljaju lokalni Datum / Vrijeme iz konteksta promatrača.

Te se klase uglavnom koriste kada vremenska zona ne treba biti izričito navedena u kontekstu. Kao dio ovog odjeljka pokrivat ćemo najčešće korištene API-je.

3.1. Raditi sa LocalDate

The LocalDate predstavlja datum u ISO formatu (gggg-MM-dd) bez vremena.

Može se koristiti za pohranu datuma kao što su rođendani i plati.

Primjer trenutnog datuma može se stvoriti iz sistemskog sata kako je dolje prikazano:

LocalDate localDate = LocalDate.now ();

The LocalDate koji predstavljaju određeni dan, mjesec i godinu mogu se dobiti pomoću "od"Ili pomoću"raščlaniti”Metoda. Na primjer, donji isječci koda predstavljaju LocalDate za 20. veljače 2015 .:

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

The LocalDate pruža razne korisne metode za dobivanje raznih informacija. Kratko zavirimo u neke od ovih API-ja.

Sljedeći isječak koda dobiva trenutni lokalni datum i dodaje jedan dan:

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

Ovaj primjer dobiva trenutni datum i oduzima jedan mjesec. Primijetite kako prihvaća nabrajanje kao vremenska jedinica:

LocalDate previousMonthSameDay = LocalDate.now (). Minus (1, ChronoUnit.MONTHS);

U sljedeća dva primjera koda raščlanjujemo datum “12.06.2016” i dobivamo dan u tjednu, odnosno dan u mjesecu. Obratite pažnju na povratne vrijednosti, prva je objekt koji predstavlja Dan u tjednu dok je drugi u an int predstavlja rednu vrijednost mjeseca:

DayOfWeek nedjelja = LocalDate.parse ("12.6.2016."). GetDayOfWeek (); int dvanaest = LocalDate.parse ("12.6.2016."). getDayOfMonth ();

Možemo testirati javlja li se datum u prijestupnoj godini. U ovom primjeru testiramo je li trenutni datum prijestupna godina:

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

Može se utvrditi da se odnos datuma s drugim pojavio prije ili nakon drugog datuma:

boolean notBefore = LocalDate.parse ("12.06.2016") .isBefore (LocalDate.parse ("11.06.2016")); boolean isAfter = LocalDate.parse ("12.06.2016") .isAfter (LocalDate.parse ("11.06.2016"));

Granice datuma mogu se dobiti od određenog datuma. U sljedeća dva primjera dobivamo LocalDateTime koji predstavlja početak dana (2016-06-12T00: 00) datog datuma i LocalDate koji predstavlja početak mjeseca (01.06.2016.):

LocalDateTime početkuOfDay = LocalDate.parse ("12.6.2016."). AtStartOfDay (); LocalDate firstDayOfMonth = LocalDate.parse ("12.6.2016.") .With (TemporalAdjusters.firstDayOfMonth ());

Pogledajmo sada kako radimo s lokalnim vremenom.

3.2. Raditi sa Lokalno vrijeme

The Lokalno vrijeme predstavlja vrijeme bez datuma.

Slično LocalDate primjerak Lokalno vrijeme može se stvoriti od sistemskog sata ili metodom “parse” i “of”. Brzi uvid u neke od najčešće korištenih API-ja u nastavku.

Primjer struje Lokalno vrijeme može se stvoriti iz sistemskog sata kao dolje:

LocalTime sada = LocalTime.now ();

U donjem uzorku koda, mi stvaramo a Lokalno vrijeme predstavlja 06:30 ujutro raščlanjivanjem niza:

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

Tvornička metoda "of" može se koristiti za stvaranje a Lokalno vrijeme. Na primjer, stvara se kod u nastavku Lokalno vrijeme predstavlja 06:30 ujutro tvorničkom metodom:

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

Primjer u nastavku stvara a Lokalno vrijeme raščlanjivanjem niza i dodaje mu sat pomoću API-ja “plus”. Rezultat bi bio Lokalno vrijeme predstavljaju 07:30:

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

Dostupne su razne metode dobivanja koje se mogu koristiti za dobivanje određenih vremenskih jedinica poput sata, min i sekundi kao što je prikazano u nastavku:

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

Također možemo provjeriti je li određeno vrijeme prije ili nakon nekog drugog određenog vremena. Donji uzorak koda uspoređuje dva Lokalno vrijeme za koju bi rezultat bio istinit:

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

Maksimalno, min i podne vrijeme mogu se dobiti konstantama u Lokalno vrijeme razred. To je vrlo korisno prilikom izvođenja upita baze podataka za pronalaženje zapisa u određenom vremenskom rasponu. Na primjer, donji kod predstavlja 23: 59: 59,99:

LocalTime maxTime = LocalTime.MAX

Sad zaronimo LocalDateTime.

3.3. Raditi sa LocalDateTime

The LocalDateTime koristi se za predstavljanje kombinacija datuma i vremena.

Ovo je najčešće korištena klasa kada trebamo kombinaciju datuma i vremena. Predaja nudi razne API-je, a mi ćemo pogledati neke od najčešće korištenih.

Primjer LocalDateTime može se dobiti iz sistemskog sata sličnog LocalDate i Lokalno vrijeme:

LocalDateTime.now ();

Slijedeći uzorci koda objašnjavaju kako stvoriti instancu koristeći tvorničke metode "of" i "parse". Rezultat bi bio LocalDateTime instanca koja zastupa 20. veljače 2015., 06:30:

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

Postoje uslužni API-ji koji podržavaju zbrajanje i oduzimanje određenih jedinica vremena kao što su dani, mjeseci, godina i minute. Dolje navedeni uzorci koda pokazuju upotrebu metoda „plus“ i „minus“. Ti se API-ji ponašaju točno kao i njihovi kolege u LocalDate i Lokalno vrijeme:

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

Dostupne su metode dobivanja za izdvajanje određenih jedinica sličnih razredima datuma i vremena. S obzirom na gornju instancu LocalDateTime, donji uzorak koda vratit će mjesec veljača:

localDateTime.getMonth ();

4. Korištenje ZonedDateTime API

Java 8 pruža ZonedDateTime kada se moramo nositi s datumom i vremenom određenim za vremensku zonu. The ZoneId je identifikator koji se koristi za predstavljanje različitih zona. Postoji oko 40 različitih vremenskih zona i ZoneId koriste se za njihovo predstavljanje na sljedeći način.

U ovom isječku koda kreiramo Zona za Pariz:

ZoneId zoneId = ZoneId.of ("Europa / Pariz"); 

Skup svih ID-ova zona može se dobiti na sljedeći način:

Postavi allZoneIds = ZoneId.getAvailableZoneIds ();

The LocalDateTime može se pretvoriti u određenu zonu:

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

The ZonedDateTime pruža raščlaniti metoda za dobivanje vremenske zone određene datuma i vremena:

ZonedDateTime.parse ("2015-05-03T10: 15: 30 + 01: 00 [Europa / Pariz]");

Drugi način rada s vremenskom zonom je pomoću OffsetDateTime. The OffsetDateTime je nepromjenjiv prikaz datuma i vremena s pomakom. Ova klasa pohranjuje sva polja datuma i vremena s preciznošću u nanosekunde, kao i odmak od UTC / Greenwicha.

The OffSetDateTime Primjer se može stvoriti kao u nastavku pomoću ZoneOffset. Ovdje stvaramo LocalDateTime koji zastupaju 6.30 sati 20. veljače 2015 .:

LocalDateTime localDateTime = LocalDateTime.of (2015, mjesec.FEBRUAR, 20, 06, 30);

Zatim vremenu dodajemo dva sata stvaranjem a ZoneOffset i postavljanje za localDateTime primjer:

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

Sada imamo localDateTime od 20.02.2015. 06:30 +02: 00. Sada prijeđimo na to kako izmijeniti vrijednosti datuma i vremena pomoću Razdoblje i Trajanje razreda.

5. Korištenje Razdoblje i Trajanje

The Razdoblje razred predstavlja količinu vremena u terminima godina, mjeseci i dana te Trajanje klasa predstavlja količinu vremena u sekundama i nano sekundama.

5.1. Raditi sa Razdoblje

The Razdoblje klasa se široko koristi za izmjenu vrijednosti datog datuma ili za dobivanje razlike između dva datuma:

LocalDate InitialDate = LocalDate.parse ("10. maj 2007.");

The Datum može se manipulirati pomoću Razdoblje kao što je prikazano u sljedećem isječku koda:

LocalDate finalDate = InitialDate.plus (Period dana (5));

The Razdoblje razred ima razne getterske metode kao što su getYears, getMonths i getDays za dobivanje vrijednosti iz a Razdoblje objekt. Primjer donjeg koda vraća int vrijednost 5 jer pokušavamo dobiti razliku u smislu dana:

int pet = Razdoblje između (početni datum, konačni datum) .getDays ();

The Razdoblje između dva datuma mogu se dobiti u određenoj jedinici, kao što su dani ili mjeseci ili godine, pomoću ChronoUnit.između:

duga petica = ChronoUnit.DAYS.bet Between (InitialDate, finalDate);

Ovaj primjer koda vraća pet dana. Nastavimo tako što ćemo pogledati Trajanje razred.

5.2. Raditi sa Trajanje

Slično Razdoblje, the Predavanje je upotreba za rješavanje Vrijeme. U sljedećem kodu kreiramo Lokalno vrijeme od 6:30 ujutro, a zatim dodajte trajanje od 30 sekundi da biste napravili a Lokalno vrijeme od 06:30:30:

LocalTime InitialTime = LocalTime.of (6, 30, 0); LocalTime finalTime = InitialTime.plus (Trajanje.sekundi (30));

The Trajanje između dva trenutka može se dobiti ili kao Trajanje ili kao specifična jedinica. U prvom isječku koda koristimo između() metoda Trajanje razreda kako bi se pronašla vremenska razlika između finalTime i InitialTime i vratite razliku u sekundama:

dugo trideset = Trajanje.između (početno vrijeme, konačno vrijeme) .getSeconds ();

U drugom primjeru koristimo između() metoda ChronoUnit klase za izvođenje iste operacije:

dugo trideset = ChronoUnit.SECONDS.bezmedu (početno vrijeme, konačno vrijeme);

Sada ćemo pogledati kako pretvoriti postojeće Datum i Kalendar na nove Datum/Vrijeme.

6. Kompatibilnost sa Datum i Kalendar

Java 8 je dodao toInstant () metoda koja pomaže pretvoriti postojeće Datum i Kalendar instanci na novi Date Time API kao u sljedećem isječku koda:

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

The LocalDateTime može se konstruirati iz epohalnih sekundi kako je dolje. Rezultat donjeg koda bio bi LocalDateTime predstavljanje 2016-06-13T11: 34: 50:

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

Krenimo sada na Datum i Vrijeme formatiranje.

7. Datum i Vrijeme Oblikovanje

Java 8 nudi API-je za jednostavno formatiranje Datum i Vrijeme:

LocalDateTime localDateTime = LocalDateTime.of (2015, mjesec.siječanj, 25, 6, 30);

Kôd u nastavku prenosi ISO format datuma za formatiranje lokalnog datuma. Rezultat bi bio 25. siječnja 2015 .:

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

The DateTimeFormatter pruža razne standardne mogućnosti oblikovanja. Prilagođeni uzorci mogu se dostaviti i za način oblikovanja, kao u nastavku, koji bi vratio a LocalDate kao 25.01.2015:

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

U stilu oblikovanja možemo preći kao KRATAK, DUGO ili SREDNJI kao dio mogućnosti oblikovanja. Donji uzorak koda dao bi izlaz koji predstavlja LocalDateTime u 25. siječnja 2015., 06:30:00:

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

Pogledajmo alternative dostupne Java 8 Coreu Datum/Vrijeme Apis.

8. Backport i zamjenske opcije

8.1. Korištenje projekta Threeten

Za organizacije koje su na putu prelaska na Javu 8 s Jave 7 ili Jave 6 i žele koristiti datum i vrijeme API-ja, projekt threeten pruža mogućnost povratne veze. Programeri mogu koristiti klase dostupne u ovom projektu kako bi postigli istu funkcionalnost kao i nova Java 8 Datum i Vrijeme API i nakon prelaska na Javu 8, paketi se mogu zamijeniti. Artefakt za projekt threeten nalazi se u središnjem spremištu maven:

 org.triza tritenbp 1.3.1 

8.2. Biblioteka Joda-Time

Druga alternativa za Javu 8 Datum i Vrijeme knjižnica je Joda-Time knjižnica. Zapravo Java 8 Datum vrijeme API-je su zajednički vodili autor biblioteke Joda-Time (Stephen Colebourne) i Oracle. Ova knjižnica pruža gotovo sve mogućnosti podržane u Javi 8 Datum vrijeme projekt. Artefakt se može pronaći u glavnom centru Mavena tako što ćete u svoj projekt uključiti donju pom ovisnost:

 joda-vrijeme joda-vrijeme 2.9.4 

9. Zaključak

Java 8 nudi bogat skup API-ja s dosljednim API dizajnom za lakši razvoj.

Uzorci koda za gornji članak mogu se naći u git spremištu Java 8 Date / Time.