1.ZonedDateTime

Date Time API 中还有一个非常有趣的类:类ZonedDateTime。它的主要目的是方便处理不同时区的日期。

LocalDate非常适合表示日期。例如,生日。无论我在哪里,我的生日都是 3 月 15 日。这是一个日期的例子。

LocalTime非常适合描述时间,就像闹钟上设置的时间:我将闹钟设置为早上 5:00,而我在哪里并不重要。凌晨 5:00 是凌晨 5:00。这是处理时间的示例。

现在假设我们正在编写一个预订航班的应用程序。飞机起飞和到达以当地时间为准。飞机在空中飞行的时间是固定的,但时区可以改变。

时区

顺便说一句,时区真是一团糟。如果您认为有 24 个时区,那您就大错特错了。

例如,印度的时间与格林威治标准时间相差五个半小时:GMT+5:30。一些国家/地区切换到夏令时,而其他国家/地区则没有。更重要的是,不同的国家在一年中的不同时间切换到夏令时。

一些国家通过法律取消夏令时,或重新引入,或再次取消。

无论如何,世界是有时区的,每个时区内都有一个时间。不同时区的时间在一年中的某些时期可能重合,而在其他时期则不同。时区通常以位于其中的主要城市命名:Europe/Monaco, Asia/Singapore,但也有例外 — US/Pacific

据官方统计,目前有 599 个时区。想一想:599。这与 24 相去甚远。欢迎来到全球化的世界。

ZoneId包中的类用于java.time在 Java 中存储时区。

顺便说一句,它有一个静态getAvailableZoneIds()方法,它返回所有当前已知时区的集合。要获取所有区域的列表,您需要编写以下代码:

代码 控制台输出(部分)
for (String s: ZoneId.getAvailableZoneIds())
   System.out.println(s);
Asia/Aden
America/Cuiaba
Etc/GMT+9
Etc/GMT+8

ZoneId要通过名称获取对象,您需要使用静态of()方法;

代码 笔记
ZoneId zone = ZoneId.of("Africa/Cairo");
Cairo


2.创建ZonedDateTime对象

创建ZonedDateTime对象时,需要调用类的静态now()方法,传递一个ZoneId对象给它。

代码 控制台输出
ZoneId zone = ZoneId.of("Africa/Cairo");
ZonedDateTime time = ZonedDateTime.now(zone);
System.out.println(time);


2019-02-22T11:37:58.074816+02:00[Africa/Cairo]

如果您不将ZoneId对象传递给该now()方法(这是允许的),则时区将根据运行该程序的计算机的设置自动确定。

例子:

代码 控制台输出
ZonedDateTime time = ZonedDateTime.now();
System.out.println(time);

2019-02-22T13:39:05.70842+02:00[Europe/Helsinki]

将全球日期转换为本地日期

其中一个有趣的特性ZonedDateTime是它能够转换为本地日期和时间。例子:

ZoneId zone = ZoneId.of("Africa/Cairo");
ZonedDateTime cairoTime = ZonedDateTime.now(zone);

LocalDate localDate = cairoTime.toLocalDate();
LocalTime localTime = cairoTime.toLocalTime();
LocalDateTime localDateTime = cairoTime.toLocalDateTime();

3. 与时间打交道

LocalDateTime类一样,该类ZonedDateTime有很多方法来获取日期和时间的各个元素。以下是这些方法的列表:

int getYear()
返回特定日期的年份
Month getMonth()
返回日期的月份:几个常量之一 -JANUARY, FEBRUARY, ...;
int getMonthValue()
返回日期所在月份的索引。一月 == 1
int getDayOfMonth()
返回一个月中的第几天的索引
DayOfWeek getDayOfWeek()
返回星期几:几个常量之一 -MONDAY, TUESDAY, ...;
int getDayOfYear()
返回一年中第几天的索引
int getHour()
返回小时数
int getMinute()
返回分钟
int getSecond()
返回秒数
int getNano()
返回纳秒

所有的方法都完全类似于类的方法LocalDateTime。当然,该类ZonedDateTime具有可让您处理日期和时间的方法。也就是说,调用方法的对象不会改变。相反,他们返回一个新ZonedDateTime对象:

方法 描述
plusYears(int)
将年份添加到日期
plusMonths(int)
将月份添加到日期
plusDays(int)
在日期中添加天数
plusHours(int)
增加小时数
plusMinutes(int)
增加分钟数
plusSeconds(int)
加秒
plusNanos(int)
添加纳秒
minusYears(int)
从日期中减去年份
minusMonths(int)
从日期中减去月份
minusDays(int)
从日期中减去天数
minusHours(int)
减去小时数
minusMinutes(int)
减去分钟
minusSeconds(int)
减秒
minusNanos(int)
减去纳秒

我们不会提供任何示例,因为我们认为通过类比我们刚才考虑的类,这里的一切都清楚了。