Heim  >  Artikel  >  Java  >  So verwenden Sie die Java8 Time API

So verwenden Sie die Java8 Time API

WBOY
WBOYnach vorne
2023-04-28 12:25:131116Durchsuche

1. Übersicht

Lassen Sie uns im Rahmen dieses Artikels mit einigen Problemen mit den vorhandenen Datums- und Kalender-APIs beginnen und untersuchen, wie die neuen Java 8-Datums- und Uhrzeit-APIs diese Probleme lösen.

Wir werfen auch einen Blick auf die Kernklassen in der Zeitklassenbibliothek von Java 8, wie LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Period, Duration und ihre APIs.

2. Probleme mit der alten API (vor Java8)

  • Thread-Sicherheit – Datums- und Kalenderklassen sind nicht threadsicher, was es für Entwickler schwierig macht, Parallelitätsprobleme mit diesen APIs zu debuggen und zusätzlichen Code schreiben zu müssen Grifffadensicherheit. Die in Java 8 eingeführten neuen Datums- und Uhrzeit-APIs sind unveränderlich und Thread-sicher, sodass diese Schwachstellen gelöst werden können.

  • API-Design und leicht zu verstehen – Die alte API ist sehr schwer zu verstehen, die Vorgänge sind sehr komplex, sehr kompliziert und bieten keine gängigen Analyse- und Konvertierungsmethoden. Die neue Zeit-API ist ISO-zentriert und folgt einem konsistenten Domänenmodell für Datum, Uhrzeit, Dauer und Zeiträume. Zur Unterstützung der gängigsten Vorgänge werden einige sehr nützliche Methoden bereitgestellt. Wir müssen einige Zeitoperationsklassen nicht mehr selbst kapseln.

  • ZonedDate und Time – Früher mussten API-Entwickler zusätzliche Logik schreiben, um die Zeitzonenlogik der alten API zu handhaben, während Sie mit der neuen API lokale und ZonedDate/Time-APIs verwenden können, um Zeitzonen zu handhaben. Sie müssen sich keine großen Gedanken über die Zeitzonenkonvertierung machen.

3. Verwenden Sie LocalDate, LocalTime und LocalDateTime

Die am häufigsten verwendeten Klassen sind LocalDate, LocalTime und LocalDateTime. Wie der Name schon sagt, repräsentieren sie lokales Datum/Uhrzeit in Kombination mit dem Kontext.

Diese Klassen werden hauptsächlich verwendet, wenn die Zeitzone nicht explizit im Kontext angegeben werden muss. In diesem Abschnitt behandeln wir die am häufigsten verwendeten APIs.

3.1. LocalDate verwenden

LocalDate stellt ein Datum ohne bestimmte Uhrzeit im ISO-Format (JJJJ-MM-TT) dar.

Es wird oft verwendet, um Geburtstage oder Gehaltstermine auszudrücken, die uns am wichtigsten sind.

Erhalten Sie das Datum unter der aktuellen Systemuhr wie folgt:

LocalDate localDate = LocalDate.now();

Ein LocalDate, das einen bestimmten Tag, Monat und Jahr darstellt, kann mit der „of“-Methode oder mit der „parse“-Methode abgerufen werden. Der folgende Codeausschnitt stellt beispielsweise das LocalDate vom 20. Februar 2015 dar:

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

Ist das nicht sehr intuitiv und praktisch? LocalDate bietet verschiedene Hilfsmethoden zum Abrufen verschiedener Datumsinformationen. Werfen wir einen kurzen Blick auf diese API-Methoden.

Der folgende Codeausschnitt ruft das aktuelle lokale Datum ab und fügt einen Tag hinzu:

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

Dieses Beispiel ruft das aktuelle Datum ab und subtrahiert einen Monat. Beachten Sie, dass eine Aufzählung als Zeiteinheit akzeptiert wird:

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

In den folgenden beiden Codebeispielen analysieren wir das Datum „2016-06-12“ und ermitteln den Wochentag bzw. den Tag des Monats. Achten Sie auf den Rückgabewert. Der erste ist ein Objekt, das DayOfWeek darstellt, und der zweite ist ein int, der den Ordnungswert des Monats darstellt:

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

Wir können testen, ob ein Datum in einem Schaltjahr auftritt Mit der alten Methode kommen wir möglicherweise nicht in den Himmel:

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

Beurteilen Sie die Reihenfolge der Daten:

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

Die Datumsgrenze kann aus dem angegebenen Datum ermittelt werden. In den folgenden beiden Beispielen erhalten wir ein LocalDateTime, das den Beginn des Tages für ein bestimmtes Datum (2016-06-12T00:00) darstellt, und ein LocalDate, das den Beginn des Monats (2016-06-01) darstellt:

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

Sehen wir uns nun an, wie wir die Ortszeit nutzen.

3.2. Verwenden Sie LocalTime

, um Zeit ohne Datum in Ortszeit darzustellen.

Ähnlich wie LocalDate können LocalTime-Instanzen aus der Systemuhr oder mithilfe der Methoden „parse“ und „of“ erstellt werden. Werfen Sie unten einen kurzen Blick auf einige häufig verwendete APIs.

Eine Instanz der aktuellen LocalTime kann wie folgt aus der Systemuhr erstellt werden:

LocalTime now = LocalTime.now();

Im folgenden Codebeispiel erstellen wir eine LocalTime, die 06:30 Uhr darstellt, indem wir die Zeichenfolgendarstellung analysieren:

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

Methode „von " Kann zum Erstellen von LocalTime verwendet werden. Der folgende Code verwendet beispielsweise die Methode „of“, um eine LocalTime zu erstellen, die 06:30 Uhr darstellt:

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

Das folgende Beispiel erstellt eine LocalTime durch Parsen einer Zeichenfolge und fügt mithilfe der „plus“-API eine Stunde hinzu. Das Ergebnis ist eine LocalTime, die 07:30 Uhr darstellt:

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

Verschiedene Getter-Methoden können verwendet werden, um bestimmte Zeiteinheiten wie Stunden, Minuten und Sekunden abzurufen. Die Stunde erhalten Sie wie folgt:

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

Gleich wie LocalDate, um zu überprüfen, ob a Eine bestimmte Zeit liegt vor oder nach einer anderen bestimmten Zeit. Das folgende Codebeispiel vergleicht zwei LocalTimes, die zu true führen:

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

Die maximale, minimale und Mittagszeit des Tages kann durch Konstanten in der LocalTime-Klasse ermittelt werden. Dies ist nützlich, wenn Sie Datenbankabfragen durchführen, um Datensätze innerhalb eines bestimmten Zeitraums zu finden. Der folgende Code stellt beispielsweise 23:59:59,99 dar:

LocalTime maxTime = LocalTime.MAX

Schauen wir uns nun LocalDateTime genauer an.

3.3. Verwendung von LocalDateTime

LocalDateTime wird verwendet, um eine Kombination aus Datum und Uhrzeit darzustellen.

Dies ist die am häufigsten verwendete Klasse, wenn wir Datum und Uhrzeit kombinieren müssen. Diese Klasse stellt verschiedene APIs bereit und wir stellen einige der am häufigsten verwendeten APIs vor.

Ähnlich wie LocalDate und LocalTime Holen Sie sich eine Instanz von LocalDateTime von der Systemuhr:

LocalDateTime.now();

下面的代码示例解释了如何使用工厂“of”和“parse”方法创建实例。结果将是代表2015年2月20日06:30 AM 的LocalDateTime实例:

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

有一些实用的API可以支持特定时间单位的时间运算,例如天,月,年和分钟。以下代码示例演示了“加”和“减”方法的用法。这些API的行为与LocalDate和LocalTime中的 API完全相同:

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

Getter方法可用于提取类似于日期和时间类的特定单位。鉴于上面的LocalDateTime实例,下面的代码示例将返回2月份的月份:

localDateTime.getMonth();

4.使用ZonedDateTime API

当我们需要处理时区特定的日期和时间时,Java 8提供了ZonedDateTime 类。ZoneID是用于表示不同区域的标识符。大约有40个不同的时区,使用ZoneID表示它们,如下所示

下面的代码我们来获取下“亚洲/上海”时区:

ZoneId zoneId = ZoneId.of("Aisa/Shanghai");

获取所有的时区:

Set<String> allZoneIds = ZoneId.getAvailableZoneIds();

LocalDateTime转化为特定的时区中的时间:

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

ZonedDateTime提供解析方法来获取时区的特定日期时间:

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

使用时区的另一种方法是使用OffsetDateTime。OffsetDateTime是具有偏移量的日期时间的不可变表示形式。此类存储所有日期和时间字段,精确到纳秒,以及从UTC/格林威治的偏移量。可以使用ZoneOffset创建OffsetDateTime实例。这里我们创建一个LocalDateTime来表示2015年2月20日上午6:30:

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

然后我们通过创建ZoneOffset并为LocalDateTime实例设置来增加两个小时:

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

我们现在的本地日期时间为2015-02-20 06:30 +02:00。现在让我们继续讨论如何使用Period和Duration类修改日期和时间值。

5.使用Period和Duration

  • Period : 用于计算两个日期(年月日)间隔。

  • Duration : 用于计算两个时间(秒,纳秒)间隔。

5.1.使用Period

Period 类被广泛地用于修改给定的日期的值或者获取两个日期之间的差值:

LocalDate initialDate = LocalDate.parse("2007-05-10");
LocalDate finalDate = initialDate.plus(Period.ofDays(5));

Period 类有各种getter方法,如getYears,getMonths和getDays从获取值周期对象。下面的代码示例返回一个int值为5,是基于上面示例的逆序操作:

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

该Period 可以在特定的单元获得两个日期之间的如天或月或数年,使用ChronoUnit.between:

int five = ChronoUnit.DAYS.between(finalDate , initialDate);

此代码示例返回五天。让我们继续看看Duration类。

5.2.使用Duration

类似Period ,该Duration类是用来处理时间。在下面的代码中,我们创建一个本地时间上午6:30,然后加30秒的持续时间,以使本地时间上午6时三十〇分30秒的:

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

两个时刻之间的持续时间可以作为持续时间或作为特定单位获得。在第一个代码片段中,我们使用Duration类的between()方法来查找finalTime和initialTime之间的时间差,并以秒为单位返回差异:

int thirty = Duration.between(finalTime, initialTime).getSeconds();

在第二个例子中,我们使用ChronoUnit类的between()方法来执行相同的操作:

int thirty = ChronoUnit.SECONDS.between(finalTime, initialTime);

现在我们来看看如何将旧的Date 和Calendar 转换为新的Date和Time。

6.与日期和日历的兼容性

Java 8添加了toInstant()方法,该方法有助于将旧API中的Date和Calendar实例转换为新的Date Time API,如下面的代码片段所示:

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

所述LocalDateTime可以从如下“ofEpochSecond"方法来构造。以下代码的结果将是代表2016-06-13T11:34:50 的LocalDateTime:

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

现在让我们继续进行日期和时间格式化。

7. 日期和时间格式化

Java 8提供了用于轻松格式化日期和时间的 API :

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

以下代码传递ISO日期格式以格式化本地日期。结果将是2015-01-25:

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

该DateTimeFormatter提供多种标准格式选项。也可以提供自定义模式来格式化方法,如下所示,它将返回LocalDate为2015/01/25:

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

我们可以将格式样式传递为SHORT,LONG或MEDIUM作为格式化选项的一部分。

下面的代码示例输出2015年1月25日06:30:00 me的输:

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

最后让我们看看Java 8 Core Date / Time API 可用的替代方案。

8.替代方案

8.1.使用Threeten 类库

对于从Java 7或Java 6这些老项目来说可以使用Threeten ,然后可以像在上面java 8一样使用相同的功能,一旦你迁移到java 8 只需要修改你的包路径代码而无需变更:

<dependency>
<groupId>org.threeten</groupId>
<artifactId>threetenbp</artifactId>
<version>LATEST</version>
</dependency>

8.2.Joda-Time类库

Java 8 日期和时间库的另一种替代方案是Joda-Time库。事实上,Java 8 Date Time API由Joda-Time库(Stephen Colebourne)和Oracle共同领导。该库提供了Java 8 Date Time项目中支持的几乎所有功能。通过在项目中引用以下pom依赖项就可以立即使用:

<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>LATEST</version>
</dependency>

Das obige ist der detaillierte Inhalt vonSo verwenden Sie die Java8 Time API. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen