Introduksjon til Joda-Time

1. Introduksjon

Joda-Time er det mest brukte databehandlingsbiblioteket før utgivelsen av Java 8. Hensikten var å tilby et intuitivt API for behandling av dato og klokkeslett og også ta opp designproblemene som eksisterte i Java Date / Time API.

De sentrale konseptene implementert i dette biblioteket ble introdusert i JDK-kjernen med utgivelsen av Java 8-versjonen. Den nye API-en for dato og klokkeslett finnes i java.time pakke (JSR-310). En oversikt over disse funksjonene finner du i denne artikkelen.

Etter utgivelsen av Java 8, anser forfatterne prosjektet for å være for det meste ferdig, og anbefaler å bruke Java 8 API hvis mulig.

2. Hvorfor bruke Joda-Time?

Dato / tid API, før Java 8, presenterte flere designproblemer.

Blant problemene er det faktum at Dato og SimpleDateFormatter klasser er ikke trådsikre. For å løse dette problemet, Joda-Time bruker uforanderlige klasser for å håndtere dato og tid.

De Dato klasse representerer ikke en faktisk dato, men i stedet spesifiserer den et øyeblikk i tid, med millisekund presisjon. Året i en Dato starter fra 1900, mens de fleste av datoperasjonene vanligvis bruker epoketid som starter fra 1. januar 1970.

Også forskyvning av dag, måned og år av a Dato er motstridende. Dagene starter klokken 0, mens måneden begynner fra 1. For å få tilgang til noen av dem, må vi bruke Kalender klasse. Joda-Time tilbyr et rent og flytende API for håndtering av datoer og klokkeslett.

Joda-Time tilbyr også støtte for åtte kalendersystemer, mens Java bare tilbyr 2: gregoriansk - java.util.GregorianCalendar og japansk - java.util.JapaneseImperialCalendar.

3. Oppsett

For å inkludere funksjonaliteten til Joda-Time-biblioteket, må vi legge til følgende avhengighet fra Maven Central:

 joda-tid joda-tid 2.10 

4. Biblioteksoversikt

Joda-Time modellerer begrepet dato og tid bruker klassene i org.joda.time pakke.

Blant disse klassene er de mest brukte:

  • LocalDate - representerer en dato uten tid
  • Lokal tid - representerer tiden uten tidssonen
  • LocalDateTime - representerer både dato og klokkeslett uten tidssone
  • Umiddelbar - representerer et nøyaktig tidspunkt i millisekunder fra Java-epoken fra 1970-01-01T00: 00: 00Z
  • Varighet - representerer varigheten i millisekunder mellom 2 tidspunkter
  • Periode - lik Varighet, men gir tilgang til individuelle komponenter i dato- og tidsobjektet, som år, måned, dager osv.
  • Intervall - representerer tidsintervallet mellom to øyeblikk

Andre viktige funksjoner er datoparsere og formaterere. Disse kan du finne i org.joda.time.format pakke.

De kalendersystem og tidssone spesifikke klasser finner du i org.joda.time.chrono og org.joda.time.tz pakker.

La oss ta en titt på noen eksempler der vi bruker de viktigste funksjonene i Joda-Time til å håndtere dato og tid.

5. Representerer dato og klokkeslett

5.1. Gjeldende dato og klokkeslett

Den nåværende datoen, uten tidsinformasjon, kan fås ved å bruke nå() metode fra de LocalDate klasse:

LocalDate currentDate = LocalDate.now ();

Når vi trenger akkurat nåværende tid, uten datoinformasjon, kan vi bruke Lokal tid klasse:

LocalTime currentTime = LocalTime.now ();

For å få en representasjon av gjeldende dato og klokkeslett uten å vurdere tidssonen, kan vi bruke LocalDateTime:

LocalDateTime currentDateAndTime = LocalDateTime.now ();

Nå, bruker currentDateAndTime, kan vi konvertere den til andre typer objekter som modellerer dato og klokkeslett.

Vi kan få en Dato tid objekt (som tar hensyn til tidssonen) ved hjelp av metoden toDateTime (). Når tid ikke er nødvendig, kan vi konvertere den til en LocalDate med metoden toLocalDate (), og når vi bare trenger tiden vi kan bruke toLocalTime () for å få en Lokal tid gjenstand:

DateTime dateTime = currentDateAndTime.toDateTime (); LocalDate localDate = currentDateAndTime.toLocalDate (); LocalTime localTime = currentDateAndTime.toLocalTime ();

Alle metodene ovenfor har en overbelastet metode som godtar a DateTimeZone gjenstand for å hjelpe oss med å representere datoen eller klokkeslettet i den angitte tidssonen:

LocalDate currentDate = LocalDate.now (DateTimeZone.forID ("America / Chicago"));

Joda-Time tilbyr også utmerket integrasjon med Java Date and Time API. Konstruktørene aksepterer a java.util.Date objekt og også, vi kan bruke toDate () metode for å returnere en java.util.Date gjenstand:

LocalDateTime currentDateTimeFromJavaDate = ny LocalDateTime (ny dato ()); Dato currentJavaDate = currentDateTimeFromJavaDate.toDate ();

5.2. Egendefinert dato og klokkeslett

For å representere tilpasset dato og tid, gir Joda-Time oss flere konstruktører. Vi kan spesifisere følgende objekter:

  • en Umiddelbar
  • en Java Dato gjenstand
  • en String representasjon av dato og klokkeslett ved hjelp av ISO-format
  • deler av dato og klokkeslett: år, måned, dag, time, minutt, sekund, millisekund
Dato oneMinuteAgoDate = ny dato (System.currentTimeMillis () - (60 * 1000)); Øyeblikkelig oneMinutesAgoInstant = ny øyeblikkelig (oneMinuteAgoDate); DateTime customDateTimeFromInstant = ny DateTime (oneMinutesAgoInstant); DateTime customDateTimeFromJavaDate = ny DateTime (oneMinuteAgoDate); DateTime customDateTimeFromString = ny DateTime ("2018-05-05T10: 11: 12.123"); DateTime customDateTimeFromParts = ny DateTime (2018, 5, 5, 10, 11, 12, 123); 

En annen måte vi kan definere en tilpasset dato og klokkeslett på, er å analysere en gitt String representasjon av dato og klokkeslett i ISO-format:

DateTime parsedDateTime = DateTime.parse ("2018-05-05T10: 11: 12.123");

Vi kan også analysere egendefinerte representasjoner av en dato og et klokkeslett ved å definere en tilpasset DateTimeFormatter:

DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern ("MM / dd / åååå HH: mm: ss"); DateTime parsedDateTimeUsingFormatter = DateTime.parse ("05.05.2018 10:11:12", dateTimeFormatter);

6. Arbeide med dato og tid

6.1. Ved hjelp av Umiddelbar

An Umiddelbar representerer antall millisekunder fra 1970-01-01T00: 00: 00Z til et gitt tidspunkt. For eksempel kan det nåværende tidspunktet oppnås ved hjelp av standardkonstruktøren eller metoden nå():

Øyeblikkelig øyeblikkelig = ny øyeblikkelig (); Øyeblikkelig. Nå ();

Å lage en Umiddelbar for et tilpasset øyeblikk kan vi bruke en av konstruktørene eller bruke metodene avEpochMilli () og ofEpochSecond ():

Instant instantFromEpochMilli = Instant.ofEpochMilli (milliesFromEpochTime); Instant instantFromEpocSeconds = Instant.ofEpochSecond (secondsFromEpochTime);

Konstruktørene aksepterer a String som representerer en dato og tid i ISO-format, en Java Dato eller a lang verdi som representerer antall millisekunder fra 1970-01-01T00: 00: 00Z:

Øyeblikkelig instantFromString = ny øyeblikkelig ("2018-05-05T10: 11: 12"); Øyeblikkelig instantFromDate = ny øyeblikkelig (oneMinuteAgoDate); Øyeblikkelig instantFromTimestamp = ny Øyeblikkelig (System.currentTimeMillis () - (60 * 1000));

Når dato og klokkeslett er representert som et String vi har muligheten til å analysere String ved hjelp av ønsket format:

Øyeblikkelig parsedInstant = Øyeblikkelig.parse ("05.05.2018 10:11:12", dateTimeFormatter);

Nå som vi vet hva Umiddelbar representerer og hvordan vi kan lage en, la oss se hvordan den kan brukes.

Å sammenligne med Umiddelbar gjenstander vi kan bruke sammenligne med() fordi den implementerer Sammenlignelig grensesnitt, men også vi kan bruke Joda-Time API-metodene som er gitt i Lesbar Øyeblikkelig grensesnitt som Umiddelbar implementerer også:

assertTrue (instantNow.compareTo (oneMinuteAgoInstant)> 0); assertTrue (instantNow.isAfter (oneMinuteAgoInstant)); assertTrue (oneMinuteAgoInstant.isBefore (instantNow)); assertTrue (oneMinuteAgoInstant.isBeforeNow ()); assertFalse (oneMinuteAgoInstant.isEqual (instantNow));

En annen nyttig funksjon er at Umiddelbar kan konverteres til en Dato tid objekt eller hendelse en Java Dato:

DateTime dateTimeFromInstant = instant.toDateTime (); Dato javaDateFromInstant = instant.toDate ();

Når vi trenger tilgang til deler av en dato og et klokkeslett, som året, timen og så videre, kan vi bruke få() metode og spesifiser en DateTimeField:

int år = instant.get (DateTimeFieldType.year ()); int måned = instant.get (DateTimeFieldType.monthOfYear ()); int dag = instant.get (DateTimeFieldType.dayOfMonth ()); int time = instant.get (DateTimeFieldType.hourOfDay ());

Nå som vi dekket Umiddelbar klasse la oss se noen eksempler på hvordan vi kan bruke Varighet, Periode og Intervall.

6.2. Ved hjelp av Varighet, Periode og Intervall

EN Varighet representerer tiden i millisekunder mellom to tidspunkter, eller i dette tilfellet kan det være to Øyeblikkelig. Vi bruker dette når vi trenger å legge til eller trekke en bestemt tid til eller fra en annen Umiddelbar uten å vurdere kronologi og tidssoner:

long currentTimestamp = System.currentTimeMillis (); lang oneHourAgo = nåværende tidsstempel - 24 * 60 * 1000; Varighet varighet = ny varighet (oneHourAgo, nåværende tidsstempel); Instant.now (). Pluss (varighet);

Vi kan også bestemme hvor mange dager, timer, minutter, sekunder eller millisekunder varigheten representerer:

lang varighetInDays = varighet.getStandardDager (); long durationInHours = duration.getStandardHours (); long durationInMinutes = duration.getStandardMinutes (); long durationInSeconds = duration.getStandardSeconds (); lang varighetInMilli = varighet.getMillis ();

Hovedforskjellen mellom Periode og Varighet er det Periode er definert i form av dato- og tidskomponenter (år, måneder, timer osv.) og representerer ikke et nøyaktig antall millisekunder. Når du bruker Periode dato- og tidsberegninger vil vurdere tidssonen og sommertid.

For eksempel å legge til en Periode fra 1 måned til 1. februar vil resultere i datorepresentasjonen 1. mars. Ved bruk av Periode biblioteket vil ta hensyn til skuddår.

Hvis vi skal bruke en Varighet vi resultatet ville ikke være riktig, fordi Varighet representerer en fast tid som ikke tar hensyn til kronologi eller tidssoner:

Periode periode = ny periode (). Med måneder (1); LocalDateTime datePlusPeriod = localDateTime.plus (periode);

An Intervall, som navnet sier, representerer datoen og tidsintervallet mellom to faste tidspunkter representert av to Umiddelbar gjenstander:

Intervallintervall = nytt intervall (oneMinuteAgoInstant, instantNow);

Klassen er nyttig når vi trenger å sjekke om to intervaller overlapper eller beregner gapet mellom dem. De overlappe () metoden vil returnere den overlappende Intervall eller null når de ikke overlapper hverandre:

Øyeblikkelig startInterval1 = ny øyeblikkelig ("2018-05-05T09: 00: 00.000"); Øyeblikkelig endInterval1 = ny øyeblikkelig ("2018-05-05T11: 00: 00.000"); Intervallintervall1 = nytt Intervall (startInterval1, endInterval1); Øyeblikkelig startInterval2 = ny øyeblikkelig ("2018-05-05T10: 00: 00.000"); Øyeblikkelig endInterval2 = ny øyeblikkelig ("2018-05-05T11: 00: 00.000"); Intervallintervall2 = nytt Intervall (startInterval2, endInterval2); Intervall overlappingInterval = intervall1.overlap (intervall2);

Forskjellen mellom intervaller kan beregnes ved hjelp av mellomrom() metode, og når vi vil vite om slutten på et intervall er lik starten på et annet intervall, kan vi bruke støter mot () metode:

assertTrue (intervall1.abuts (nytt intervall (ny øyeblikkelig ("2018-05-05T11: 00: 00.000"), ny øyeblikkelig ("2018-05-05T13: 00: 00.000"))));

6.3. Dato- og klokkeslettoperasjoner

Noen av de vanligste operasjonene er å legge til, trekke fra og konvertere dato og tid. Biblioteket gir spesifikke metoder for hver av klassene LocalDate, Lokal tid, LocalDateTime, og Dato tid. Det er viktig å merke seg at disse klassene er uforanderlige slik at hver metodeinnkallelse vil skape et nytt objekt av sin type.

La oss ta LocalDateTime for øyeblikket og prøv å endre verdien:

LocalDateTime currentLocalDateTime = LocalDateTime.now ();

Å legge til en ekstra dag til currentLocalDateTime vi bruker plusDays () metode:

LocalDateTime nextDayDateTime = currentLocalDateTime.plusDays (1);

Vi kan også bruke i tillegg til() metode for å legge til en Periode eller Varighet til vår currentLocalDateTime:

Periode oneMonth = ny periode (). MedMonths (1); LocalDateTime nextMonthDateTime = currentLocalDateTime.plus (oneMonth);

Metodene er like for de andre dato- og tidskomponentene, for eksempel, plusYears () for å legge til ekstra år, plusSeconds () for å legge til flere sekunder og så videre.

Å trekke en dag fra vår currentLocalDateTime vi kan bruke minusDager () metode:

LocalDateTime previousDayLocalDateTime = currentLocalDateTime.minusDays (1);

Foruten å gjøre beregninger med dato og klokkeslett, kan vi også sette individuelle deler av datoen eller klokkeslettet. For eksempel kan du sette timen til 10 ved å bruke withHourOfDay () metode. Andre metoder som starter med prefikset "med" kan brukes til å stille inn komponenter for den datoen eller klokkeslettet:

LocalDateTime currentDateAtHour10 = currentLocalDateTime .withHourOfDay (0) .withMinuteOfHour (0) .withSecondOfMinute (0) .withMillisOfSecond (0);

Et annet viktig aspekt er at vi kan konvertere fra en dato og tidsklasse til en annen. For å gjøre dette kan vi bruke spesifikke metoder levert av biblioteket:

  • toDateTime () - konverterer LocalDateTime til en Dato tid gjenstand
  • toLocalDate () - konverterer LocalDateTime til en LocalDate gjenstand
  • toLocalTime () - konverterer LocalDateTime til et LocalTime-objekt
  • toDate () - konverterer LocalDateTime til en Java Dato gjenstand

7. Arbeide med tidssoner

Joda-Time gjør det enkelt for oss å jobbe med forskjellige tidssoner og byttet mellom dem. Vi har DateTimeZone abstrakt klasse som brukes til å representere alle aspekter angående en tidssone.

Standard tidssone som brukes av Joda-Time er valgt fra user.timezone Java-systemegenskap. Bibliotekets API lar oss spesifisere, individuelt for hver klasse eller beregning, hvilken tidssone som skal brukes. For eksempel kan vi opprette et LocalDateTime-objekt

Når vi vet at vi vil bruke en bestemt tidssone i hele applikasjonen, kan vi angi standard tidssone:

DateTimeZone.setDefault (DateTimeZone.UTC);

Fra nå av blir alle dato- og klokkeslettoperasjonene, hvis ikke annet er spesifisert, representert i UTC-tidssonen.

For å se alle tilgjengelige tidssoner kan vi bruke metoden getAvailableIDs ():

DateTimeZone.getAvailableIDs ()

Når vi trenger å representere datoen eller klokkeslettet i en bestemt tidssone, kan vi bruke noen av klassene Lokal tid, LocalDate, LocalDateTime, Dato tid og spesifiser i konstruktøren DateTimeZone gjenstand:

DateTime dateTimeInChicago = ny DateTime (DateTimeZone.forID ("America / Chicago")); DateTime dateTimeInBucharest = ny DateTime (DateTimeZone.forID ("Europe / Bucharest")); LocalDateTime localDateTimeInChicago = ny LocalDateTime (DateTimeZone.forID ("America / Chicago"));

Når vi konverterer mellom disse klassene, kan vi også spesifisere ønsket tidssone. Metoden toDateTime () aksepterer a DateTimeZone objekt og toDate () godtar java.util.TimeZone-objekt:

DateTime convertDateTime = localDateTimeInChicago.toDateTime (DateTimeZone.forID ("Europe / Bucharest")); Dato convertDate = localDateTimeInChicago.toDate (TimeZone.getTimeZone ("Europa / Bucuresti"));

8. Konklusjon

Joda-Time er et fantastisk bibliotek som startet med hovedmålet å fikse problemene i JDK angående dato- og tidsoperasjoner. Det ble snart den de facto bibliotek for håndtering av dato og klokkeslett og nylig ble hovedkonseptene fra det introdusert i Java 8.

Det er viktig å merke seg at forfatteren vurderer det “Å være et stort sett ferdig prosjekt” og anbefaler å migrere den eksisterende koden for å bruke Java 8-implementeringen.

Kildekoden for artikkelen er tilgjengelig på GitHub.


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