# Java `ZonedDateTime`类

> 原文： [https://howtodoinjava.com/java/date-time/zoneddatetime-class/](https://howtodoinjava.com/java/date-time/zoneddatetime-class/)

[Java 8 中引入](https://howtodoinjava.com/java8/date-and-time-api-changes-in-java-8-lambda/)的`java.time.ZonedDateTime`类表示 **ISO-8601** 日历系统中具有时区信息的日期和时间。 此类存储所有日期和时间字段，精度为纳秒。

我们可以使用`ZonedDateTime`实例来代表全球分布的用户的时间。 例如，我们可以使用`ZonedDateTime`传达会议日期，参加者将根据他们的本地日期和时间在线连接。

`ZonedDateTime`的状态等于三个单独的对象：[`LocalDateTime`](https://howtodoinjava.com/java/java-localdatetime-class/)，`ZoneId`和已解析的`ZoneOffset`。

注意，`ZonedDateTime`实例是[**不可变的**](https://howtodoinjava.com/java/basics/how-to-make-a-java-class-immutable/)和[**线程安全**](https://howtodoinjava.com/java/multi-threading/what-is-thread-safety/)。

## 1\. `ZonedDateTime`类声明

```java
public final class ZonedDateTime
	extends Object
	implements Temporal, ChronoZonedDateTime<LocalDate>, Serializable
{
	//class body
}

```

## 2\. 如何创建`ZonedDateTime`

通常，我们将在两种情况下创建`ZonedDateTime`实例，即获取具有区域信息的当前时间戳或创建代表特定时区的时间戳。

#### 2.1 获取当前的`ZonedDateTime`

使用以下工厂方法获取当前时间戳。

```java
ZonedDateTime now = ZonedDateTime.now();

ZonedDateTime now = ZonedDateTime.now( ZoneId.of("GMT+05:30") ); //Time in IST

```

#### 2.2 创建指定的`ZonedDateTime`

要创建带有特定日期，时间和区域信息的时间戳，请使用以下方法。

```java
//1 - All date parts are inplace
ZoneId zoneId = ZoneId.of("UTC+1");

ZonedDateTime zonedDateTime1 =
    ZonedDateTime.of(2015, 11, 30, 23, 45, 59, 1234, zoneId);

//=========

//2 - Using existing local date and time values 
LocalDate localDate = LocalDate.of(2019, 03, 12);
LocalTime localTime = LocalTime.of(12,  44);
ZoneId zoneId = ZoneId.of("GMT+05:30");

ZonedDateTime timeStamp = ZonedDateTime.of( localDate, localTime, zoneId );

```

## 3\. 如何将字符串解析为`ZonedDateTime`

`ZonedDateTime`类具有两个重载的`parse()`方法，用于将字符串中的时间转换为本地时间实例。

```java
parse(CharSequence text)	//1

parse(CharSequence text, DateTimeFormatter formatter)	//2

```

*   如果字符串以[`ISO_ZONED_DATE_TIME`](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_ZONED_DATE_TIME)模式包含时间，即`2019-03-28T10:15:30+01:00[Europe/Paris]`则使用第一种方法。 这是默认模式。
*   对于任何其他日期时间模式，我们都需要使用第二种方法，在该方法中我们将日期时间作为字符串传递，并使用格式化器来表示该日期时间字符串的模式。

```java
//1 - default pattern
String timeStamp = "2019-03-27T10:15:30";
ZonedDateTime localTimeObj = ZonedDateTime.parse(time);

//2 - specified pattern
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss a");
String timeStamp1 = "2019-03-27 10:15:30 AM";
ZonedDateTime localTimeObj1 = ZonedDateTime.parse(timeStamp1, formatter);

```

## 4\. 如何将`ZonedDateTime`格式化为字符串

使用`ZonedDateTime.format(DateTimeFormatter)`方法将本地时间格式化为所需的字符串表示形式。

```java
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss a");

ZonedDateTime now = ZonedDateTime.now();

String dateTimeString = now.format(formatter);	//2019-03-28 14:47:33 PM

```

## 5\. 如何修改`ZonedDateTime`

`ZonedDateTime`提供以下修改方法。 所有方法都返回`ZonedDateTime`的新实例，因为现有实例始终是不可变的。

*   `plusYears()`
*   `plusMonths()`
*   `plusDays()`
*   `plusHours()`
*   `plusMinutes()`
*   `plusSeconds()`
*   `plusNanos()`
*   `minusYears()`
*   `minusMonths()`
*   `minusDays()`
*   `minusHours()`
*   `minusMinutes()`
*   `minusSeconds()`
*   `minusNanos()`

```java
ZonedDateTime now = ZonedDateTime.now();

//3 hours later
ZonedDateTime zonedDateTime1 = now.plusHours(3);	

//3 minutes earliar
ZonedDateTime zonedDateTime2 = now.minusMinutes(3);

//Next year same time
ZonedDateTime zonedDateTime2 = now.plusYears(1);

//Last year same time
ZonedDateTime zonedDateTime2 = now.minusYears(1);

```

## 6\. 更多例子

[将`ZonedDateTime`格式化为字符串](https://howtodoinjava.com/java/date-time/format-zoneddatetime/)

[将字符串解析为`ZonedDateTime`](https://howtodoinjava.com/java/date-time/zoneddatetime-parse/)

[在 Java 中将`LocalDate`转换为`ZonedDateTime`](https://howtodoinjava.com/java/date-time/localdate-zoneddatetime-conversion/)

[`ZonedDateTime`时区转换示例](https://howtodoinjava.com/java/date-time/convert-date-between-timezones/)

[比较`ZonedDateTime`实例](https://howtodoinjava.com/java/date-time/zoneddatetime-comparison/)

[Java 8 – 将字符串解析为 UTC 中的日期时间](https://howtodoinjava.com/java8/parse-string-to-date-time-utc-gmt/)

在评论中向我发送有关 Java 8 `ZonedDateTime`类的问题。

学习愉快！

参考： [`ZonedDateTime` Java 文档](https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html)