Inleiding tot de Java 8 Date / Time API

1. Overzicht

Java 8 introduceerde nieuwe API's voor Datum en Tijd om de tekortkomingen van ouderen aan te pakken java.util.Date en java.util.Calendar.

Laten we als onderdeel van dit artikel beginnen met de problemen in het bestaande Datum en Kalender API's en laten we bespreken hoe de nieuwe Java 8 Datum en Tijd API's pakken ze aan.

We zullen ook kijken naar enkele van de kernklassen van het nieuwe Java 8-project die deel uitmaken van het java.time pakket zoals LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Period, Duration en hun ondersteunde API's.

2. Problemen met het bestaande Datum/Tijd API's

  • Draadveiligheid - De Datum en Kalender klassen zijn niet thread-safe, waardoor ontwikkelaars de hoofdpijn van moeilijk te debuggen gelijktijdigheidsproblemen moeten oplossen en extra code moeten schrijven om de thread-veiligheid af te handelen. Integendeel, het nieuwe Datum en Tijd API's die in Java 8 zijn geïntroduceerd, zijn onveranderlijk en thread-safe, waardoor ontwikkelaars die hoofdpijn van gelijktijdigheid wegnemen.
  • API's-ontwerp en gemakkelijk te begrijpen - De Datum en Kalender API's zijn slecht ontworpen met inadequate methoden om dagelijkse bewerkingen uit te voeren. De nieuwe Datum Tijd API's zijn ISO-gericht en volgen consistente domeinmodellen voor datum, tijd, duur en perioden. Er is een grote verscheidenheid aan hulpprogramma-methoden die de meest voorkomende bewerkingen ondersteunen.
  • ZonedDate en Tijd - Ontwikkelaars moesten extra logica schrijven om tijdzonelogica af te handelen met de oude API's, terwijl met de nieuwe API's tijdzone kan worden afgehandeld met Lokaal en ZonedDate/Tijd API's.

3. Met behulp van LocalDate, Lokale tijd en LocalDateTime

De meest gebruikte klassen zijn LocalDate, Lokale tijd en LocalDateTime. Zoals hun namen aangeven, vertegenwoordigen ze de lokale datum / tijd vanuit de context van de waarnemer.

Deze klassen worden voornamelijk gebruikt wanneer de tijdzone niet expliciet in de context hoeft te worden gespecificeerd. Als onderdeel van deze sectie behandelen we de meest gebruikte API's.

3.1. Werken met LocalDate

De LocalDate vertegenwoordigt een datum in ISO-formaat (jjjj-MM-dd) zonder tijd.

Het kan worden gebruikt om datums zoals verjaardagen en betaaldagen op te slaan.

Een exemplaar van de huidige datum kan worden gemaakt op basis van de systeemklok, zoals hieronder:

LocalDate localDate = LocalDate.now ();

De LocalDate die een specifieke dag, maand en jaar vertegenwoordigen, kunnen worden verkregen met behulp van de “van"Methode of door de"ontleden”Methode. De onderstaande codefragmenten vertegenwoordigen bijvoorbeeld de LocalDate voor 20 februari 2015:

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

De LocalDate biedt verschillende hulpprogramma's om een ​​verscheidenheid aan informatie te verkrijgen. Laten we een korte blik werpen op enkele van deze API-methoden.

Het volgende codefragment haalt de huidige lokale datum op en voegt een dag toe:

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

In dit voorbeeld wordt de huidige datum opgehaald en wordt er één maand afgetrokken. Merk op hoe het een opsomming als tijdseenheid:

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

In de volgende twee codevoorbeelden ontleden we de datum "2016-06-12" en krijgen respectievelijk de dag van de week en de dag van de maand. Let op de geretourneerde waarden, het eerste is een object dat de Dag van de week terwijl de tweede in een int vertegenwoordigt de ordinale waarde van de maand:

DayOfWeek sunday = LocalDate.parse ("2016-06-12"). GetDayOfWeek (); int twaalf = LocalDate.parse ("2016-06-12"). getDayOfMonth ();

We kunnen testen of een datum in een schrikkeljaar valt. In dit voorbeeld testen we of de huidige datum een ​​schrikkeljaar is:

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

De relatie van een datum met een andere kan worden bepaald voor of na een andere datum:

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"));

Datumgrenzen kunnen worden verkregen vanaf een bepaalde datum. In de volgende twee voorbeelden krijgen we de LocalDateTime dat staat voor het begin van de dag (2016-06-12T00: 00) van de opgegeven datum en de LocalDate dat staat voor respectievelijk het begin van de maand (2016-06-01):

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

Laten we nu eens kijken hoe we met lokale tijd werken.

3.2. Werken met Lokale tijd

De Lokale tijd vertegenwoordigt tijd zonder datum.

Gelijkwaardig aan LocalDate een exemplaar van Lokale tijd kan worden gemaakt op basis van de systeemklok of door de methode "parse" en "of" te gebruiken. Kijk snel naar enkele van de veelgebruikte API's hieronder.

Een exemplaar van current Lokale tijd kan worden gemaakt op basis van de systeemklok zoals hieronder:

LocalTime nu = LocalTime.now ();

In het onderstaande codevoorbeeld, we creëren een Lokale tijd vertegenwoordigt 06:30 AM door een stringvoorstelling te ontleden:

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

De fabrieksmethode "of" kan worden gebruikt om een Lokale tijd. De onderstaande code maakt bijvoorbeeld Lokale tijd vertegenwoordigt 06:30 uur volgens de fabrieksmethode:

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

Het onderstaande voorbeeld maakt een Lokale tijd door een string te ontleden en er een uur aan toe te voegen met behulp van de "plus" API. Het resultaat zou zijn Lokale tijd vertegenwoordigt 07:30 uur:

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

Er zijn verschillende vangmethoden beschikbaar die kunnen worden gebruikt om specifieke tijdseenheden zoals uur, minuten en seconden te krijgen, zoals hieronder:

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

We kunnen ook controleren of een bepaald tijdstip voor of na een ander specifiek tijdstip valt. Het onderstaande codevoorbeeld vergelijkt twee Lokale tijd waarvoor het resultaat waar zou zijn:

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

De max, min en middagtijd van een dag kunnen worden verkregen door constanten in Lokale tijd klasse. Dit is erg handig bij het uitvoeren van databasequery's om records binnen een bepaalde tijdspanne te vinden. De onderstaande code staat bijvoorbeeld voor 23:59: 59,99:

LocalTime maxTime = LocalTime.MAX

Laten we nu eens kijken LocalDateTime.

3.3. Werken met LocalDateTime

De LocalDateTime wordt gebruikt om te vertegenwoordigen een combinatie van datum en tijd.

Dit is de meest gebruikte klasse wanneer we een combinatie van datum en tijd nodig hebben. De klas biedt een verscheidenheid aan API's en we zullen enkele van de meest gebruikte bekijken.

Een exemplaar van LocalDateTime kan worden verkregen uit de systeemklok vergelijkbaar met LocalDate en Lokale tijd:

LocalDateTime.now ();

In de onderstaande codevoorbeelden wordt uitgelegd hoe u een instantie kunt maken met behulp van de fabrieksmethoden "of" en "parse". Het resultaat zou een zijn LocalDateTime instantie die 20 februari 2015, 06.30 uur vertegenwoordigt:

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

Er zijn hulpprogramma-API's om het optellen en aftrekken van specifieke tijdseenheden zoals dagen, maanden, jaar en minuten te ondersteunen. De onderstaande codevoorbeelden demonstreren het gebruik van "plus" en "min" -methoden. Deze API's gedragen zich precies zoals hun tegenhangers in LocalDate en Lokale tijd:

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

Getter-methoden zijn beschikbaar om specifieke eenheden te extraheren die vergelijkbaar zijn met de datum- en tijdklassen. Gezien het bovenstaande voorbeeld van LocalDateTime, zal het onderstaande codevoorbeeld de maand februari retourneren:

localDateTime.getMonth ();

4. Met behulp van ZonedDateTime API

Java 8 biedt ZonedDateTime wanneer we te maken hebben met tijdzonespecifieke datum en tijd. De ZoneId is een identificatie die wordt gebruikt om verschillende zones weer te geven. Er zijn ongeveer 40 verschillende tijdzones en de ZoneId worden gebruikt om ze als volgt weer te geven.

In dit codefragment maken we een Zone voor Parijs:

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

Een set van alle zone-id's kan als volgt worden verkregen:

Stel allZoneIds = ZoneId.getAvailableZoneIds ();

De LocalDateTime kan worden geconverteerd naar een specifieke zone:

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

De ZonedDateTime biedt ontleden methode om een ​​tijdzone-specifieke datum en tijd te krijgen:

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

Een andere manier om met de tijdzone te werken, is door OffsetDateTime. De OffsetDateTime is een onveranderlijke weergave van een datum-tijd met een offset. Deze klasse slaat alle datum- en tijdvelden op tot op nanoseconden nauwkeurig, evenals de offset ten opzichte van UTC / Greenwich.

De OffSetDateTime instantie kan worden gemaakt zoals hieronder met ZoneOffset. Hier maken we een LocalDateTime vertegenwoordigt 06.30 uur op 20 februari 2015:

LocalDateTime localDateTime = LocalDateTime.of (2015, maand.FEBRUARI, 20, 06, 30);

Vervolgens tellen we twee uur bij de tijd op door een ZoneOffset en instelling voor de localDateTime voorbeeld:

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

We hebben nu een localDateTime van 2015-02-20 06:30 +02: 00. Laten we nu verder gaan met het wijzigen van datum- en tijdwaarden met de Periode en Looptijd klassen.

5. Met behulp van Periode en Looptijd

De Periode klasse vertegenwoordigt een hoeveelheid tijd in termen van jaren, maanden en dagen en de Looptijd klasse vertegenwoordigt een hoeveelheid tijd in termen van seconden en nanoseconden.

5.1. Werken met Periode

De Periode klasse wordt veel gebruikt om waarden van een bepaalde datum te wijzigen of om het verschil tussen twee datums te verkrijgen:

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

De Datum kan worden gemanipuleerd met Periode zoals weergegeven in het volgende codefragment:

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

De Periode class heeft verschillende getter-methoden zoals getYears, getMonths en getDays om waarden te krijgen van een Periode voorwerp. Het onderstaande codevoorbeeld retourneert een int waarde van 5 omdat we proberen het verschil in dagen te krijgen:

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

De Periode tussen twee datums kan worden verkregen in een specifieke eenheid, zoals dagen of maand of jaren, met ChronoUnit. Tussen:

lange vijf = ChronoUnit.DAYS.between (initialDate, finalDate);

Dit codevoorbeeld retourneert vijf dagen. Laten we doorgaan met het bekijken van het Looptijd klasse.

5.2. Werken met Looptijd

Gelijkwaardig aan Periode, de Duur les is handig om mee om te gaan Tijd. In de volgende code maken we een Lokale tijd van 6.30 uur en voeg dan een duur van 30 seconden toe om een Lokale tijd van 06:30:30 uur:

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

De Looptijd tussen twee momenten kan worden verkregen als een Looptijd of als een specifieke eenheid. In het eerste codefragment gebruiken we de tussen() methode van de Looptijd klas om het tijdsverschil tussen te vinden laatste keer en initialTime en geef het verschil in seconden terug:

lange dertig = Duur.between (initialTime, finalTime) .getSeconds ();

In het tweede voorbeeld gebruiken we de tussen() methode van de ChronoUnit klasse om dezelfde bewerking uit te voeren:

lange dertig = ChronoUnit.SECONDS.between (initialTime, finalTime);

Nu zullen we bekijken hoe we bestaande kunnen converteren Datum en Kalender naar nieuw Datum/Tijd.

6. Compatibiliteit met Datum en Kalender

Java 8 heeft het toInstant () methode die helpt bij het converteren van bestaande Datum en Kalender instantie naar nieuwe Date Time API zoals in het volgende codefragment:

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

De LocalDateTime kan worden opgebouwd uit epochseconden zoals hieronder. Het resultaat van de onderstaande code zou een LocalDateTime vertegenwoordigt 2016-06-13T11: 34: 50:

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

Laten we nu verder gaan Datum en Tijd formatteren.

7. Datum en Tijd Formatteren

Java 8 biedt API's voor het eenvoudig formatteren van Datum en Tijd:

LocalDateTime localDateTime = LocalDateTime.of (2015, maand.JANUARI, 25, 6, 30);

De onderstaande code geeft een ISO-datumnotatie door om de lokale datum op te maken. Het resultaat zou 25-01-2015 zijn:

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

De DateTimeFormatter biedt verschillende standaardopmaakopties. Aangepaste patronen kunnen ook worden opgegeven om de methode te formatteren, zoals hieronder, die een LocalDate als 2015/01/25:

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

We kunnen de opmaakstijl ook doorgeven als KORT, LANG of MEDIUM als onderdeel van de opmaakoptie. Het onderstaande codevoorbeeld zou een uitvoer geven die vertegenwoordigt LocalDateTime in 25 jan. 2015, 06:30:00:

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

Laten we eens kijken naar alternatieven die beschikbaar zijn voor Java 8 Core Datum/Tijd API's.

8. Backport en alternatieve opties

8.1. Project Threeten gebruiken

Voor organisaties die op weg zijn naar Java 8 vanuit Java 7 of Java 6 en de datum- en tijd-API willen gebruiken, biedt project threeten de backport-mogelijkheid. Ontwikkelaars kunnen klassen gebruiken die in dit project beschikbaar zijn om dezelfde functionaliteit te bereiken als die van de nieuwe Java 8 Datum en Tijd API en zodra ze naar Java 8 zijn verplaatst, kunnen de pakketten worden omgeschakeld. Artefacten voor het project threeten zijn te vinden in de centrale opslagplaats van maven:

 org.threeten threetenbp 1.3.1 

8.2. Joda-Time-bibliotheek

Een ander alternatief voor Java 8 Datum en Tijd bibliotheek is de Joda-Time-bibliotheek. In feite Java 8 Datum Tijd API's worden gezamenlijk geleid door de auteur van de Joda-Time-bibliotheek (Stephen Colebourne) en Oracle. Deze bibliotheek biedt vrijwel alle mogelijkheden die worden ondersteund in Java 8 Datum Tijd project. Het artefact kan worden gevonden in de centrale maven door de onderstaande pom-afhankelijkheid in uw project op te nemen:

 joda-tijd joda-tijd 2.9.4 

9. Conclusie

Java 8 biedt een uitgebreide set API's met een consistent API-ontwerp voor eenvoudigere ontwikkeling.

De codevoorbeelden voor het bovenstaande artikel zijn te vinden in de Java 8 Date / Time git-repository.


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