Java8中新增日期时间API的使用(小豆丁技术栈)

目录
  1. 1. 一、简介
  2. 2. 二、新时间 API 的组成
  3. 3. 三、概念
    1. 3.1. 1、时间与时刻
    2. 3.2. 2、时间戳和时区
    3. 3.3. 3、GM 和 UTC
    4. 3.4. 4、UTC 和 GMT 差别
    5. 3.5. 5、时间输出格式类型
  4. 4. 四、主要类介绍
  5. 5. 五、常用示例
    1. 5.1. 1、Instant
    2. 5.2. 2、Clock
    3. 5.3. 3、Duration
    4. 5.4. 4、LocalDate
    5. 5.5. 5、LocalTime
    6. 5.6. 6、LocalDateTime
    7. 5.7. 7、ZoneDateTime
    8. 5.8. 8、Period
    9. 5.9. 9、ZoneId
    10. 5.10. 10、ZoneOffset

一、简介

       从 Java 1.0 开始,就提供了对日期与时间处理的 java.util.Date 类,它允许把日期解释为年、月、日、小时、分钟和秒值,也允许格式化和解析日期字符串。不过,这些函数的 API 不易于实现国际化。在升级版本到 Java 1.1 前,Java 维护者认为 Date 类很难被重新构造,由于这个原因,Java 1.1 增加了一个新的 java.util.Calendar 类。Calendar 类实现日期和时间字段之间转换,使用 DateFormat 类来格式化和解析日期字符串。可是在开发者使用过程中感受到,Calendar 类并不比 Date 类好用,它们面临的部分问题是:

  • 可变性:像时间和日期这样的类应该是不可变的。
  • 偏移性:Date 中的年份是从 1900 开始的,而月份是从 0 开始的,不太符合常识习惯。
  • 类命名:Date 并不表示处理”日期”,而”Calendar”类也不全是表示”日历”,类命名比较不合理。
  • 格式化:时间日期格式化只对 Date 有用,Calendar 则不行,且时间格式化对象存在线程安全问题。

自 2001 年起 Joda-Time 项目发布,它提供了简单易用且线程安全的时间类库,很快在 Java 社区中流行并广泛使用。Java 维护人员考虑到 JDK 中也需要一个这样的库,于是就与巴西的 Michael Nascimento Santos 合作,Java 官方 JDK 新增了的时间/日期 API的进程(JSR-310)。

二、新时间 API 的组成

新增的时间 API 由 5 个包组成,如下:

三、概念

一些基础概念有助于我们更加理解时间类,所以我们需要了解一下。

1、时间与时刻

  • 时间: 可以表示准确的时刻或日期,也可以表示一个时间段。
  • 时刻: 指某一瞬bai间,表示具体的某一时间点,只是时间中的一个点。

2、时间戳和时区

  • 时间戳: 时间戳是指格林尼治时间1970年01月01日00时00分00秒到现在的总秒数(毫秒数),可以理解成绝对时间,它与时区无关,不同时区对同一时间戳的解读不一样
  • 时区: 同一时刻(时间戳),世界上各地区的时间可能是不一样的,具体时间与时区相关,按经度一共分为24个时区,英国格林尼治是0时区,中国北京是东8区

3、GM 和 UTC

       每个地区都有自己的本地时间,在网上以及无线电通信中时间转换的问题就显得格外突出。整个地球分为二十四时区,每个时区都有自己的本地时间。在国际无线电通信场合,为了统一起见,使用一个统一的时间,都与英国伦敦的本地时相同:

  • GMT: Greenwich Mean Time 格林尼治标准时间。
  • UTC: Coordinated Universal Time 协调世界时,又称世界统一时间,世界标准时间,国际协调时间。

例如,北京时区是东八区,领先 UTC 八个小时,在电子邮件信头的 Date 域记为+0800,如果在电子邮件的信头中有这么一行 Date:Fri, 08 Nov 2020 10:30:00 +0800 说明信件的发送地的地方时间是 **2020 年 11 月 8 号,星期五,早上 10:30:00,这个地方的本地时领先 UTC 8 个小时(+0800,就是东八区时间)**。电子邮件信头的 Date 域使用二十四小时的时钟,而不使用 AM 和 PM 来标记上下午。

以上面电子邮件的发送时间为例,如果要把这个时间转化为UTC,可以使用一下公式:

1
UTC + 时区差 = 本地时间

时区差东为正,西为负。在此,把东八区时区差记为 +0800,

1
UTC + 0800 = 北京时间(本地时间)

那么 UTC 时间为:

1
北京时间(本地时间) - 0800 = UTC

4、UTC 和 GMT 差别

简单的说 UTC 和 GMT 基本相等,但是 UTC 比 GMT 时间更为精准,他们区别如下:

  • UTC 是我们现在用得时间标准,GMT 是老的时间计量标准。
  • UTC 是根据原子钟来计算时间,GMT 是根据地球的自转和公转来计算时间,也就是太阳每天经过英国伦敦郊区的皇家格林威治天文台的时间就是中午12点。
  • 由于现在世界上最精确的原子钟50亿年才会误差1秒(最精确原子钟问世:50亿年误差一秒),可以说非常精确。而 GMT 因为是根据地球的转动来计算时间的,而地球的自转正在缓速变慢,所以使用 GMT 的话,总有一天可能会变为,显示中午12点,但是实际并不是一天太阳当头照的时候,很可能就是早上或晚上。所以 UTC 更加精确。

5、时间输出格式类型

输出类型 描述
2019-06-10T03:48:20.847Z 世界标准时间,T:日期和时间分隔,Z:世界标准时间
2019-06-10T11:51:48.872 不含时区信息的时间
2019-06-10T11:55:04.421+08:00[Asia/Shanghai] 包含时区信息的时间,+08:00 表示相对于0时区加 8 小时,[Asia/Shanghai]:时区

四、主要类介绍

JDK 8 新时间 API 中增加了很多处理时间的类,主要有如下:

  • Instant: 表示时刻,即时间线上的一个瞬时点,精确到纳秒,常用于获取纪元时的秒、毫秒等时间戳,它提供了一系列的 minusXxx() 方法用于在当前时刻基础减去一段时间,也提供了 plusXxx() 方法在当前时刻基础加上一段时间;
  • Clock: 表示时钟,此类常用于查找当前时刻,也用于获取指定时区的日期、时间,该类可以取代 System.currentTimeMillis() 方法,也提供了很多获取当前日期、时间的方法;
  • Duration: 表示持续时间,此类以秒和纳秒为单位对时间量进行建模,常用于处理两个日期的时间段。
  • LocalDate: 表示日期(内部不记录时区),通常由”年”、”月”、”日”组成,该类封装了很多操作日期的方法。例如,当前日期加上或者减去几天、几月、几年等;
  • LocalTime: 表示时间(内部不记录时区),通常由”时”、”分”、”秒”组成,该类封装了很多操作时间的方法。例如,当前时间加上或者减去几秒、几分、几小时等;
  • LocalDateTime: 表示日期时间(内部不记录时区),是”时间”与”日期”的组合,该类封装了很多操作时间日期的方法,例如,当前时间加上或者减去几年、几月、几时、几分、几秒等;
  • ZoneDateTime: 表示日期时间(内部记录时区),方法和 LocalDateTime 类似;
  • Period: 表示基于日期的时间量,用年、月和日来模拟时间的数量或数量;
  • ZoneId: 表示时区,”+01:00”和”Europe/Paris” ZoneId 除了处理与标准时间的时间差还处理地区时(夏令时,冬令时等)
  • ZoneOffset: 表示时区偏移量,ZoneOffset 是 ZoneId 的子类,相对于格林尼治时间(GMT)的时间偏差,只处理与格林尼治的时间差;

五、常用示例

新的时间 API 提供了很多时间操作类和方法,不过常用的是 LocalDate 和 LocalDateTime,下面是各个类的方法使用示例,可以简单看看,在实际中如果是需要可以参考使用:

1、Instant

表示时刻,时间线上的一个瞬时点,常用于获取纪元时的秒、毫秒等时间戳。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  1import java.time.Instant;
2import java.time.temporal.ChronoUnit;
3import java.util.Date;
4
5public class InstantExample {
6
7 /**
8 * 获取时刻并进行转换
9 */
public static void instantTransition() {
/* 获取时刻 */
// 获取当前时刻
Instant instant = Instant.now();
// 获取当前时刻的纳秒
long microsecond = instant.getNano();
// 获取当前时刻按纪元时转换后的毫秒(从1970-01-01T00:00:00Z.起)
long millisecond = instant.toEpochMilli();
// 获取当前时刻按纪元时转换后的秒(从1970-01-01T00:00:00Z.起)
long second = instant.getEpochSecond();
/* 输出 */
System.out.println("获取当前时刻:" + instant);
System.out.println("获取当前时间的纳秒:" + microsecond);
System.out.println("获取当前时刻按纪元时转换后的毫秒:" + millisecond);
System.out.println("获取当前时刻按纪元时转换后的秒:" + second);
System.out.println("-------------------------------------------------");
}

/**
* 时刻比较
*/
public static void instantCompare() {
/* 根据毫秒创建两个时刻 */
Instant instant1 = Instant.ofEpochMilli(1591113400000L);
Instant instant2 = Instant.ofEpochMilli(1591113410000L);
/* 两个时刻间比较 */
// 比较两个 Instant 时刻,如果返回是正数则大于,否则相反
int difference = instant1.compareTo(instant2);
// 比较 instant1 是否在 instant2 时刻之后
boolean isAfter = instant1.isAfter(instant2);
// 比较 instant1 是否在 instant2 时刻之前
boolean isBefore = instant1.isBefore(instant2);
/* 输出 */
System.out.println("比较 instant1 是否在 instant2 时刻之后:" + isAfter);
System.out.println("比较 instant1 是否在 instant2 时刻之前:" + isBefore);
System.out.println("比较 Instant 对象的差值:" + difference);
System.out.println("-------------------------------------------------");
}

/**
* 时刻计算
*/
public static void instantCalculation() {
/* 获取当前时刻 */
Instant instant = Instant.now();
/* 时刻计算 */
// 计算3天前的时间
Instant instantPlus = instant.plus(3, ChronoUnit.DAYS);
// 计算6天前的时间
Instant instantMinus = instant.minus(6, ChronoUnit.DAYS);
System.out.println("计算3天后的时刻:" + instantPlus);
System.out.println("计算6天前的时刻:" + instantMinus);
/* 根据毫秒创建两个时刻 */
Instant instant1 = Instant.ofEpochMilli(1591113400000L);
Instant instant2 = Instant.ofEpochMilli(1591113410000L);
// 计算两个 Instant 之间的秒数(如果返回负数则大于,返回负数则小于)
long diffAsMinutes = ChronoUnit.SECONDS.between(instant1, instant2);
/* 输出 */
System.out.println("计算两个 Instant 之间的分钟数:" + diffAsMinutes);
System.out.println("-------------------------------------------------");
}

/**
* Instant 用于时刻转换的静态方法
*/
public static void instantStaticMethod() {
/* 时刻的静态转换方法 */
// 通过纪元时(秒)获取时刻(从1970-01-01T00:00:00Z.起)
Instant epochSecond = Instant.ofEpochSecond(1591113458L);
// 通过纪元时(秒)获取时刻并设置纳秒(从1970-01-01T00:00:00Z.起)
Instant epochSecondNano = Instant.ofEpochSecond(1591113458L, 100);
// 通过纪元时(毫秒)获取时刻(从1970-01-01T00:00:00Z.起)
Instant epochMilli = Instant.ofEpochMilli(1591113458000L);
// 通过纪元时(毫秒)将 Date 转换为 Instant 对象
Date date = new Date();
Instant dateInstant = Instant.ofEpochMilli(date.getTime());
// 通过纪元时(毫秒)将 Instant 转换为 Date 对象
Date instantDate = new Date(Instant.now().toEpochMilli());
/* 输出 */
System.out.println("通过纪元时(秒)获取时刻:" + epochSecond);
System.out.println("通过纪元时(秒)获取时刻并设置纳秒:" + epochSecondNano);
System.out.println("通过纪元时(毫秒)获取时刻" + epochMilli);
System.out.println("Date 转换 Instant 对象:" + dateInstant);
System.out.println("Instant 转换 Date 对象:" + instantDate);
System.out.println("-------------------------------------------------");
}

public static void main(String[] args) {
// 获取时刻并进行转换
instantTransition();
// 时刻比较
instantCompare();
// 时刻计算
instantCalculation();
// Instant 用于时刻转换的静态方法
instantStaticMethod();
}

}

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
## 获取时刻并进行转换
-------------------------------------------------
获取当前时刻:2020-07-06T15:00:07.860Z
获取当前时间的纳秒:860000000
获取当前时刻按纪元时转换后的毫秒:1594047607860
获取当前时刻按纪元时转换后的秒:1594047607
-------------------------------------------------

## 时刻比较
-------------------------------------------------
比较 instant1 是否在 instant2 时刻之后:false
比较 instant1 是否在 instant2 时刻之前:true
比较 Instant 对象的差值:-1
-------------------------------------------------

## 时刻计算
-------------------------------------------------
计算3天后的时刻:2020-07-09T15:00:07.917Z
计算6天前的时刻:2020-06-30T15:00:07.917Z
计算两个 Instant 之间的分钟数:10
-------------------------------------------------

## Instant 用于时刻转换的静态方法
-------------------------------------------------
通过纪元时(秒)获取时刻:2020-06-02T15:57:38Z
通过纪元时(秒)获取时刻并设置纳秒:2020-06-02T15:57:38.000000100Z
通过纪元时(毫秒)获取时刻2020-06-02T15:57:38Z
Date 转换 Instant 对象:2020-07-06T15:00:07.918Z
Instant 转换 Date 对象:Mon Jul 06 23:00:07 CST 2020
-------------------------------------------------

2、Clock

表示时钟,此类常用于查找当前时刻。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;

public class ClockExample {

/**
* 获取时钟
*/
public static void getClock(){
/* 获取时钟 */
// 获取"系统时间"的时钟,并使用"UTC时区"对日期和时间进行转换
Clock utcClock = Clock.systemUTC();
// 获取"系统时间"的时钟,并使用"系统时区"对日期和时间进行转换
Clock systemZoneClock = Clock.systemDefaultZone();
// 获取"系统时间"的时钟,并使用"指定时区"对日期和时间进行转换
Clock zoneClock = Clock.system(ZoneId.of("Asia/Shanghai"));
// 获取"固定时刻"的时钟,并"指定时区"对日期和时间进行转换
Clock fixedClock = Clock.fixed(Instant.now(), ZoneId.of("Asia/Shanghai"));
/* 输出 */
System.out.println("获取\"系统时间\"的时钟,并使用\"UTC时区\"对日期和时间进行转换:" + utcClock);
System.out.println("获取\"系统时间\"的时钟,并使用\"系统时区\"对日期和时间进行转换:" + systemZoneClock);
System.out.println("获取\"系统时间\"的时钟,并使用\"指定时区\"对日期和时间进行转换:" + zoneClock);
System.out.println("获取\"固定时刻\"的时钟,并\"指定时区\"对日期和时间进行转换:" + fixedClock);
System.out.println("-------------------------------------------------");
}

/**
* 时钟实例中的方法
*/
public static void clockMethod() {
/* 获取系统时钟 */
Clock clock = Clock.systemDefaultZone();
/* 时钟常用方法 */
// 获取当前时钟的时刻
Instant instant = clock.instant();
// 获取当前时钟的当前毫秒时刻
long millis = clock.millis();
// 获取当前时钟的时区
ZoneId zoneId = clock.getZone();
// 获取当前时钟并指定时区
Clock zoneClock = clock.withZone(ZoneId.of("Asia/Shanghai"));
/* 输出 */
System.out.println("获取当前时间的时钟,并使用UTC时区对日期和时间进行转换:" + clock);
System.out.println("获取时钟的当前时刻:" + instant);
System.out.println("获取时钟的当前毫秒瞬间:" + millis);
System.out.println("获取用于创建日期和时间的时区:" + zoneId);
System.out.println("返回带有不同时区的此时钟的副本:" + zoneClock);
System.out.println("-------------------------------------------------");
}

public static void main(String[] args) {
// 获取时钟实例
getClock();
// 时钟实例中的方法
clockMethod();
}

}

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## 获取时钟
--------------------------------------------------------------------------------------------------
获取"系统时间"的时钟,并使用"UTC时区"对日期和时间进行转换:SystemClock[Z]
获取"系统时间"的时钟,并使用"系统时区"对日期和时间进行转换:SystemClock[Asia/Shanghai]
获取"系统时间"的时钟,并使用"指定时区"对日期和时间进行转换:SystemClock[Asia/Shanghai]
获取"固定时刻"的时钟,并"指定时区"对日期和时间进行转换:FixedClock[2020-07-06T14:56:56.362Z,Asia/Shanghai]
--------------------------------------------------------------------------------------------------

## 时钟实例中的方法
--------------------------------------------------------------------------------------------------
获取当前时间的时钟,并使用UTC时区对日期和时间进行转换:SystemClock[Asia/Shanghai]
获取时钟的当前时刻:2020-07-06T14:56:56.372Z
获取时钟的当前毫秒瞬间:1594047416372
获取用于创建日期和时间的时区:Asia/Shanghai
返回带有不同时区的此时钟的副本:SystemClock[Asia/Shanghai]
--------------------------------------------------------------------------------------------------

3、Duration

表示时间段,此类以秒和纳秒为单位对时间量进行建模,也用于处理两个日期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.time.Duration;
import java.time.LocalDateTime;

public class DurationExample {

/**
* 计算时间段
*/
public static void dateDuration(){
/* 创建两个时间对象 */
LocalDateTime time1 = LocalDateTime.of(2018, 6,18,10,20,30);
LocalDateTime time2 = LocalDateTime.of(2020, 8,22,12,20,30);
// 创建时间段对象
Duration duration = Duration.between(time1, time2);
/* 输出 */
System.out.println("小时时间段:" + duration.toHours());
System.out.println("分钟时间段:" + duration.toMinutes());
System.out.println("秒时间段:" + duration.getSeconds());
System.out.println("毫秒时间段:" + duration.toMillis());
System.out.println("-------------------------------------------------");
}

public static void main(String[] args) {
// 计算时间段
dateDuration();
}

}

输出如下:

1
2
3
4
5
6
7
## 计算时间段
-------------------------------------------------
小时时间段:19106
分钟时间段:1146360
秒时间段:68781600
毫秒时间段:68781600000
-------------------------------------------------

4、LocalDate

表示日期,通常由”年”、”月”、”日”组成,该类封装了很多操作日期的方法;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class LocalDateExample {

/**
* 日期转换
*/
public static void localDateTransition() {
/* 在默认时区中从系统时钟获取当前日期 */
LocalDate localDate = LocalDate.now();
/* 日期转换 */
// 使用指定的格式化程序格式化此日期
String formatLocalDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
// 指定年、月、日参数获取日期实例
LocalDate ymdLocalDate = LocalDate.of(2020, 6, 18);
// 指定年和年中的天数参数获取日期实例
LocalDate ydLocalDate = LocalDate.ofYearDay(2020, 100);
// 通过纪元时(天)获取日期实例(从1970-01-01起)
LocalDate epochDayLocalDate = LocalDate.ofEpochDay(10);
/* 输出 */
System.out.println("在默认时区中从系统时钟获取当前日期:" + localDate);
System.out.println("使用指定的格式化程序格式化此日期:" + formatLocalDate);
System.out.println("根据设置年、月、日参数获取日期实例:" + ymdLocalDate);
System.out.println("指定年和年中的天数参数获取日期实例:" + ydLocalDate);
System.out.println("通过纪元时(天)获取日期实例:" + epochDayLocalDate);
System.out.println("-------------------------------------------------");
}

/**
* 日期比较
*/
public static void localDateCompare() {
/* 创建两个日期实例 */
LocalDate localDate1 = LocalDate.of(2020, 6, 18);
LocalDate localDate2 = LocalDate.of(2020, 6, 17);
/* LocalDate 日期比较 */
// 比较两个 LocalDate 日期,如果返回是正数则大于,否则相反
int difference = localDate1.compareTo(localDate2);
// 检查此日期是否在指定的日期之后
boolean isAfter = localDate1.isAfter(localDate2);
boolean isBefore = localDate1.isBefore(localDate2);
/* 输出 */
System.out.println("比较 LocalDate 对象的差值:" + difference);
System.out.println("检查此日期是否在指定的日期之后:" + isAfter);
System.out.println("检查此日期是否在指定的日期之前:" + isBefore);
System.out.println("-------------------------------------------------");
}

/**
* 日期计算
*/
public static void localDateCalculation() {
/* 在默认时区中从系统时钟获取当前日期 */
LocalDate localDate = LocalDate.now();
/* 日期计算 */
// 获取在当前日期基础(增加)指定(天数)的日期
LocalDate plusLocalDate = localDate.plusDays(10);
// 获取在当前日期基础(减少)指定(天数)的日期
LocalDate minusLocalDate = localDate.minusDays(10);
/* 输出 */
System.out.println("获取在当前日期基础(增加)指定(天数)的日期:" + plusLocalDate);
System.out.println("获取在当前日期基础(减少)指定(天数)的日期:" + minusLocalDate);
System.out.println("-------------------------------------------------");
}

/**
* 检查是否为闰年
*/
public static void checkLeapYear() {
LocalDate localDate = LocalDate.now();
boolean isLeapYear = localDate.isLeapYear();
System.out.println(isLeapYear ? "今年是闰年" : "今年不是闰年");
System.out.println("-----------------------------------");
}

public static void main(String[] args) {
// 日期转换
localDateTransition();
// 日期比较
localDateCompare();
// 日期计算
localDateCalculation();
// 检查是否为闰年
checkLeapYear();
}

}

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
## 日期转换
-------------------------------------------------
在默认时区中从系统时钟获取当前日期:2020-07-06
使用指定的格式化程序格式化此日期:2020/07/06
根据设置年、月、日参数获取日期实例:2020-06-18
指定年和年中的天数参数获取日期实例:2020-04-09
通过纪元时(天)获取日期实例:1970-01-11
-------------------------------------------------

## 日期比较
-------------------------------------------------
比较 LocalDate 对象的差值:1
检查此日期是否在指定的日期之后:true
检查此日期是否在指定的日期之前:false
-------------------------------------------------

## 日期计算
-------------------------------------------------
获取在当前日期基础(增加)指定(天数)的日期:2020-07-16
获取在当前日期基础(减少)指定(天数)的日期:2020-06-26
-------------------------------------------------

## 检查是否为闰年
-------------------------------------------------
今年是闰年
-------------------------------------------------

5、LocalTime

表示时间,通常由”时”、”分”、”秒”组成,该类封装了很多操作时间的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class LocalTimeExample {

/**
* 时间转换
*/
public static void localTimeTransition() {
/* 在默认时区中从系统时钟获取当前时间 */
LocalTime localTime = LocalTime.now();
/* 时间转换 */
// 使用指定的格式化程序格式化此时间
String formatLocalTime = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
// 指定时、分参数获取时间实例
LocalTime hmLocalTime = LocalTime.of(12, 30);
// 指定时、分、秒参数获取时间实例
LocalTime hmsLocalTime = LocalTime.of(12, 30, 20);
// 指定时、分、秒、纳秒参数获取时间实例
LocalTime hmsnLocalTime = LocalTime.of(12, 30, 20, 10000);
// 指定秒参数获取时间实例
LocalTime secondOfDayLocalTime = LocalTime.ofSecondOfDay(3600);
/* 输出 */
System.out.println("在默认时区中从系统时钟获取当前时间:" + localTime);
System.out.println("使用指定的格式化程序格式化此时间:" + formatLocalTime);
System.out.println("指定时、分参数获取时间实例:" + hmLocalTime);
System.out.println("指定时、分、秒参数获取时间实例:" + hmsLocalTime);
System.out.println("指定时、分、秒、纳秒参数获取时间实例:" + hmsnLocalTime);
System.out.println("指定秒参数获取时间实例:" + secondOfDayLocalTime);
System.out.println("-------------------------------------------------");
}

/**
* 时间比较
*/
public static void localTimeCompare() {
/* 创建两个时间实例 */
LocalTime localTime1 = LocalTime.of(12, 30);
LocalTime localTime2 = LocalTime.of(12, 25);
/* 时间比较 */
// 比较两个 LocalTime 时间,如果返回是正数则大于,否则相反
int difference = localTime1.compareTo(localTime2);
// 检查此时间是否在指定的时间之后
boolean isAfter = localTime1.isAfter(localTime2);
boolean isBefore = localTime1.isBefore(localTime2);
/* 输出 */
System.out.println("比较 LocalTime 对象的差值:" + difference);
System.out.println("检查此时间是否在指定的时间之后:" + isAfter);
System.out.println("检查此时间是否在指定的时间之前:" + isBefore);
System.out.println("-------------------------------------------------");
}

/**
* 时间计算
*/
public static void localTimeCalculation() {
/* 在默认时区中从系统时钟获取当前时间 */
LocalTime localTime = LocalTime.now();
/* 时间计算 */
// 获取在当前时间基础(增加)指定(秒)的时间
LocalTime plusSecondsLocalTime = localTime.plusSeconds(10);
// 获取在当前时间基础(增加)指定(分钟)的时间
LocalTime plusMinutesLocalTime = localTime.plusMinutes(10);
// 获取在当前时间基础(增加)指定(小时)的时间
LocalTime plusHoursLocalTime = localTime.plusHours(10);
// 获取在当前时间基础(减少)指定(秒)的时间
LocalTime minusSecondsLocalTime = localTime.minusSeconds(10);
// 获取在当前时间基础(减少)指定(分钟)的时间
LocalTime minusMinutesLocalTime = localTime.minusMinutes(10);
// 获取在当前时间基础(减少)指定(小时)的时间
LocalTime minusHoursLocalTime = localTime.minusHours(10);
/* 输出 */
System.out.println("获取在当前时间基础(增加)指定(秒)的时间:" + plusSecondsLocalTime);
System.out.println("获取在当前时间基础(增加)指定(分钟)的时间:" + plusMinutesLocalTime);
System.out.println("获取在当前时间基础(增加)指定(小时)的时间:" + plusHoursLocalTime);
System.out.println("获取在当前时间基础(减少)指定(秒)的时间:" + minusSecondsLocalTime);
System.out.println("获取在当前时间基础(减少)指定(分钟)的时间:" + minusMinutesLocalTime);
System.out.println("获取在当前时间基础(减少)指定(小时)的时间:" + minusHoursLocalTime);
System.out.println("-------------------------------------------------");
}

public static void main(String[] args) {
/* 时间转换 */
localTimeTransition();
/* 时间比较 */
localTimeCompare();
/* 时间计算 */
localTimeCalculation();
}

}

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

## 时间转换
--------------------------------------------------------
在默认时区中从系统时钟获取当前时间:23:14:11.746
使用指定的格式化程序格式化此时间:11:14:11
指定时、分参数获取时间实例:12:30
指定时、分、秒参数获取时间实例:12:30:20
指定时、分、秒、纳秒参数获取时间实例:12:30:20.000010
指定秒参数获取时间实例:01:00
--------------------------------------------------------

## 时间比较
--------------------------------------------------------
比较 LocalTime 对象的差值:1
检查此时间是否在指定的时间之后:true
检查此时间是否在指定的时间之前:false
--------------------------------------------------------

## 时间计算
--------------------------------------------------------
获取在当前时间基础(增加)指定(秒)的时间:23:14:21.759
获取在当前时间基础(增加)指定(分钟)的时间:23:24:11.759
获取在当前时间基础(增加)指定(小时)的时间:09:14:11.759
获取在当前时间基础(减少)指定(秒)的时间:23:14:01.759
获取在当前时间基础(减少)指定(分钟)的时间:23:04:11.759
获取在当前时间基础(减少)指定(小时)的时间:13:14:11.759
--------------------------------------------------------

6、LocalDateTime

表示日期时间,只不过该类不记录时区信息,是”时间”与”日期”的组合,该类封装了很多操作时间日期的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
  1import java.time.*;
2import java.time.format.DateTimeFormatter;
3import java.time.temporal.ChronoField;
4import java.time.temporal.ChronoUnit;
5import java.time.temporal.ValueRange;
6import java.util.Date;
7
8public class LocalDateTimeExample {
9
/**
* 时间转换
*/
public static void localDateTimeTransition() {
/* 在默认时区中从系统时钟获取当前时间日期 */
LocalDateTime localDateTime = LocalDateTime.now();
/* 在指定时区中从系统时钟获取当前时间日期*/
LocalDateTime localDateTimeZone = LocalDateTime.now(ZoneId.of("+08:00"));
/* 时间转换 */
// 获取该日期时间是属于该(年)的第几天
int dayOfYear = localDateTime.getDayOfYear();
// 获取该日期时间是属于该(月)的第几天
int dayOfMonth = localDateTime.getDayOfMonth();
// 获取该日期时间是属于该(周)的第几天
DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
// 从时间日期中获取(年)信息
int year = localDateTime.getYear();
// 从时间日期中获取(月)信息
Month month = localDateTime.getMonth();
// 从时间日期中获取(小时)信息
int hour = localDateTime.getHour();
// 从时间日期中获取(分钟)信息
int minute = localDateTime.getMinute();
// 从时间日期中获取(秒)信息
int second = localDateTime.getSecond();
// 从时间日期中获取(纳秒)信息
int nano = localDateTime.getNano();
// 使用指定的格式化程序格式化时间日期
String formatLocalDateTimeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// 使用制度的格式格式化字符串到时间日期
LocalDateTime fromatLocalDateTime = LocalDateTime.parse("2020-09-18 10:30:50",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// 指定年、月、日、时、分参数获取日期时间实例
LocalDateTime ymdhmLocalDateTime = LocalDateTime.of(2020, 6, 18, 12, 30);
// 指定年、月、日、时、分、秒参数获取日期时间实例
LocalDateTime ymdhmsLocalDateTime = LocalDateTime.of(2020, 6, 18, 12, 30, 20);
// 指定使用纪元时(秒)参数获取时间实例
LocalDateTime epochSecondLocalDateTime = LocalDateTime.ofEpochSecond(30 * 366 * 24 * 60 * 60, 0, ZoneOffset.UTC);
/* 输出 */
System.out.println("在默认时区中从系统时钟获取当前时间日期:" + localDateTime);
System.out.println("在指定时区中从系统时钟获取当前时间日期:" + localDateTimeZone);
System.out.println("获取该日期时间是属于该(年)的第几天:" + dayOfYear);
System.out.println("获取该日期时间是属于该(月)的第几天:" + dayOfMonth);
System.out.println("获取该日期时间是属于该(周)信息,名:" + dayOfWeek.name() + "天值" + dayOfWeek.getValue());
System.out.println("从时间日期中获取(年)信息:" + year);
System.out.println("从时间日期中获取(月份)信息,名:" + month.name() + "月份值" + month.getValue());
System.out.println("从时间日期中获取(小时)信息:" + hour);
System.out.println("从时间日期中获取(分钟)信息:" + minute);
System.out.println("从时间日期中获取(秒)信息:" + second);
System.out.println("从时间日期中获取(纳秒)信息:" + nano);
System.out.println("在默认时区中从系统时钟获取当前日期时间:" + localDateTime);
System.out.println("使用指定的格式化程序格式化时间日期:" + formatLocalDateTimeStr);
System.out.println("使用制度的格式格式化字符串到时间日期:" + fromatLocalDateTime);
System.out.println("指定年、月、日、时、分参数获取日期时间实例:" + ymdhmLocalDateTime);
System.out.println("指定年、月、日、时、分、秒参数获取日期时间实例:" + ymdhmsLocalDateTime);
System.out.println("指定使用纪元时(秒)参数获取时间实例:" + epochSecondLocalDateTime);
System.out.println("-------------------------------------------------");
}

/**
* 日期时间比较
*/
public static void localDateTimeCompare() {
/* 创建两个日期时间实例 */
LocalDateTime localDateTime1 = LocalDateTime.of(2020,6,18,11, 30);
LocalDateTime localDateTime2 = LocalDateTime.of(2020,6,18,12, 30);
/* 日期时间比较 */
// 比较两个 LocalDateTime 日期时间,如果返回是正数则大于,否则相反
int difference = localDateTime1.compareTo(localDateTime2);
// 检查此日期时间是否在指定的日期之后
boolean isAfter = localDateTime1.isAfter(localDateTime2);
boolean isBefore = localDateTime1.isBefore(localDateTime2);
// 以指定单位计算直到另一个日期时间的时间量并指定时间单位
long until = localDateTime1.until(localDateTime2, ChronoUnit.SECONDS);
/* 输出 */
System.out.println("比较 LocaDatelTime 对象的差值:" + difference);
System.out.println("检查此日期时间是否在指定的时间之后:" + isAfter);
System.out.println("检查此日期时间是否在指定的时间之前:" + isBefore);
System.out.println("以指定单位计算直到另一个日期时间的时间量并指定时间单位:" + until);
System.out.println("-------------------------------------------------");
}

/**
* 日期时间计算
*/
public static void localDateTimeCalculation() {
/* 获取日期时间对象 */
// 在默认时区中从系统时钟获取当前日期时间
LocalDateTime localDateTime = LocalDateTime.now();
// 获取在当前日期时间基础(增加)指定(秒)的日期时间
LocalDateTime plusSecondsLocalDateTime = localDateTime.plusSeconds(30);
// 获取在当前日期时间基础(增加)指定(分钟)的日期时间
LocalDateTime plusMinutesLocalDateTime = localDateTime.plusMinutes(10);
// 获取在当前日期时间基础(增加)指定(小时)的日期时间
LocalDateTime plusHoursLocalDateTime = localDateTime.plusHours(10);
// 获取在当前日期时间基础(增加)指定(天)的日期时间
LocalDateTime plusDaysLocalDateTime = localDateTime.plusDays(10);
// 获取在当前日期时间基础(增加)指定(周)的日期时间
LocalDateTime plusWeeksLocalTime = localDateTime.plusWeeks(1);
// 获取在当前日期时间基础(增加)指定(年)的日期时间
LocalDateTime plusYearsLocalTime = localDateTime.plusYears(1);
// 获取在当前日期时间基础(减少)指定(秒)的日期时间
LocalDateTime minusSecondsLocalDateTime = localDateTime.minusSeconds(30);
// 获取在当前日期时间基础(减少)指定(分钟)的日期时间
LocalDateTime minusMinutesLocalTime = localDateTime.minusMinutes(30);
// 获取在当前日期时间基础(减少)指定(小时)的日期时间
LocalDateTime minusHoursLocalTime = localDateTime.minusHours(10);
// 获取在当前日期时间基础(减少)指定(天)的日期时间
LocalDateTime minusDaysLocalTime = localDateTime.minusDays(10);
// 获取在当前日期时间基础(减少)指定(周)的日期时间
LocalDateTime minusWeeksLocalTime = localDateTime.minusWeeks(1);
// 获取在当前日期时间基础(减少)指定(年)的日期时间
LocalDateTime minusYearsLocalTime = localDateTime.minusYears(1);
/* 输出 */
System.out.println("获取在当前日期时间基础(增加)指定(秒)的日期时间:" + plusSecondsLocalDateTime);
System.out.println("获取在当前日期时间基础(增加)指定(分钟)的日期时间:" + plusMinutesLocalDateTime);
System.out.println("获取在当前日期时间基础(增加)指定(小时)的日期时间:" + plusHoursLocalDateTime);
System.out.println("获取在当前日期时间基础(增加)指定(天)的日期时间:" + plusDaysLocalDateTime);
System.out.println("获取在当前日期时间基础(增加)指定(周)的日期时间:" + plusWeeksLocalTime);
System.out.println("获取在当前日期时间基础(增加)指定(年)的日期时间:" + plusYearsLocalTime);
System.out.println("获取在当前日期时间基础(减少)指定(秒)的日期时间:" + minusSecondsLocalDateTime);
System.out.println("获取在当前日期时间基础(减少)指定(分钟)的日期时间:" + minusMinutesLocalTime);
System.out.println("获取在当前日期时间基础(减少)指定(小时)的日期时间:" + minusHoursLocalTime);
System.out.println("获取在当前日期时间基础(减少)指定(天)的日期时间:" + minusDaysLocalTime);
System.out.println("获取在当前日期时间基础(减少)指定(周)的日期时间:" + minusWeeksLocalTime);
System.out.println("获取在当前日期时间基础(减少)指定(年)的日期时间:" + minusYearsLocalTime);
System.out.println("-------------------------------------------------");
}

/**
* Instance 转换为 LocalDateTime 转换
*/
public static void instantToLocalDateTime(){
/* 创建 Instant 对象 */
Instant instant = Instant.now();
/* Instant 和 LocalDateTime 对象互转 */
// 将 Instant 对象转换为 LocalDateTime 对象并设置时区
LocalDateTime zoneLocalDateTime = LocalDateTime.ofInstant(instant,ZoneId.of("UTC"));
// 将 LocalDateTime 对象转换为 Instant
Instant localDateTaimeToInstant = zoneLocalDateTime.toInstant(ZoneOffset.UTC);
/* 输出 */
System.out.println("将 Instant 对象转换为 LocalDateTime 对象并设置时区:" + zoneLocalDateTime);
System.out.println("将 LocalDateTime 对象转换为 Instant:" + localDateTaimeToInstant);
System.out.println("-------------------------------------------------");
}

/**
* LocalTime 与 LocalDateTime 转换
*/
public static void localTime(){
/* 获取本地日期时间对象 */
LocalDateTime localDateTime = LocalDateTime.now();
/* 获取指定字段的有效值范围 */
// 获取指定字段的有效值范围(天/年)
ValueRange valueRangeDayOfYear = localDateTime.range(ChronoField.DAY_OF_YEAR);
// 获取指定字段的有效值范围(天/星期)
ValueRange valueRangeDayOfWeek = localDateTime.range(ChronoField.DAY_OF_WEEK);
/* 输出 */
System.out.println("获取指定字段的有效值范围,今年天数最大值:" + valueRangeDayOfYear.getMaximum());
System.out.println("获取指定字段的有效值范围,今年天数最小值:" + valueRangeDayOfYear.getMinimum());
System.out.println("获取指定字段的有效值范围,这星期数最大值:" + valueRangeDayOfWeek.getMaximum());
System.out.println("获取指定字段的有效值范围,这星期数最小值:" + valueRangeDayOfWeek.getMinimum());
System.out.println("-------------------------------------------------");
}


/**
* LocalDateTime 与 Date 的相互转换
*/
public static void localDateTimeAndDate(){
// Date 转换为 LocalDateTime
Date date1 = new Date();
LocalDateTime localDateTime1 = LocalDateTime.ofInstant(date1.toInstant(), ZoneId.systemDefault());
// LocalDateTime 转换为 Date
LocalDateTime localDateTime2 = LocalDateTime.now();
Date date2 = Date.from(localDateTime2.atZone(ZoneId.systemDefault()).toInstant());
/* 输出 */
System.out.println("Date 转换为 LocalDateTime:" + localDateTime1);
System.out.println("LocalDateTime转换为Date :" + date2);
}

public static void main(String[] args) {
// 日期时间转换
localDateTimeTransition();
// 日期时间比较
localDateTimeCompare();
// 日期时间计算
localDateTimeCalculation();
// instant 转换为 LocalDateTime 对象
instantToLocalDateTime();
// LocalTime 与 LocalDateTime 转换
localTime();
// LocalDateTime 与 Date 的相互转换
localDateTimeAndDate();
}

}

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
## 时间转换
-----------------------------------------------------------------------------
在默认时区中从系统时钟获取当前时间日期:2020-07-06T23:10:32.791
在指定时区中从系统时钟获取当前时间日期:2020-07-06T23:10:32.791
获取该日期时间是属于该(年)的第几天:188
获取该日期时间是属于该(月)的第几天:6
获取该日期时间是属于该(周)信息,名:MONDAY天值1
从时间日期中获取(年)信息:2020
从时间日期中获取(月份)信息,名:JULY月份值7
从时间日期中获取(小时)信息:23
从时间日期中获取(分钟)信息:10
从时间日期中获取(秒)信息:32
从时间日期中获取(纳秒)信息:791000000
在默认时区中从系统时钟获取当前日期时间:2020-07-06T23:10:32.791
使用指定的格式化程序格式化日期时间:2020-07-06 11:10:32
指定年、月、日、时、分参数获取日期时间实例:2020-06-18T12:30
指定年、月、日、时、分、秒参数获取日期时间实例:2020-06-18T12:30:20
指定使用纪元时(秒)参数获取时间实例:2000-01-24T00:00
-----------------------------------------------------------------------------

## 日期时间比较
-----------------------------------------------------------------------------
比较 LocaDatelTime 对象的差值:-1
检查此日期时间是否在指定的时间之后:false
检查此日期时间是否在指定的时间之前:true
以指定单位计算直到另一个日期时间的时间量并指定时间单位:3600
-----------------------------------------------------------------------------

## 日期时间计算
-----------------------------------------------------------------------------
获取在当前日期时间基础(增加)指定(秒)的日期时间:2020-07-06T23:11:02.805
获取在当前日期时间基础(增加)指定(分钟)的日期时间:2020-07-06T23:20:32.805
获取在当前日期时间基础(增加)指定(小时)的日期时间:2020-07-07T09:10:32.805
获取在当前日期时间基础(增加)指定(天)的日期时间:2020-07-16T23:10:32.805
获取在当前日期时间基础(增加)指定(周)的日期时间:2020-07-13T23:10:32.805
获取在当前日期时间基础(增加)指定(年)的日期时间:2021-07-06T23:10:32.805
获取在当前日期时间基础(减少)指定(秒)的日期时间:2020-07-06T23:10:02.805
获取在当前日期时间基础(减少)指定(分钟)的日期时间:2020-07-06T22:40:32.805
获取在当前日期时间基础(减少)指定(小时)的日期时间:2020-07-06T13:10:32.805
获取在当前日期时间基础(减少)指定(天)的日期时间:2020-06-26T23:10:32.805
获取在当前日期时间基础(减少)指定(周)的日期时间:2020-06-29T23:10:32.805
获取在当前日期时间基础(减少)指定(年)的日期时间:2019-07-06T23:10:32.805
-----------------------------------------------------------------------------

## Instance 转换为 LocalDateTime 转换
-----------------------------------------------------------------------------
将 Instant 对象转换为 LocalDateTime 对象并设置时区:2020-07-06T15:10:32.806
将 LocalDateTime 对象转换为 Instant:2020-07-06T15:10:32.806Z
-----------------------------------------------------------------------------

## LocalTime 与 LocalDateTime 转换
-----------------------------------------------------------------------------
获取指定字段的有效值范围,今年天数最大值:366
获取指定字段的有效值范围,今年天数最小值:1
获取指定字段的有效值范围,这星期数最大值:7
获取指定字段的有效值范围,这星期数最小值:1
-----------------------------------------------------------------------------

## LocalDateTime 与 Date 的相互转换
-----------------------------------------------------------------------------
Date 转换为 LocalDateTime:2020-07-06T23:10:32.806
LocalDateTime转换为Date :Mon Jul 06 23:10:32 CST 2020
-----------------------------------------------------------------------------

7、ZoneDateTime

该类中的方法基本和 LocalDateTime 一致,不过该类会记录时区信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import java.time.*;

public class ZonedDateTimeExample {

/**
* ZonedDateTime 转换
*/
public static void zoneTimeTransition() {
/* 在默认时区中从系统时钟获取当前日期时间 */
ZonedDateTime zonedDateTime = ZonedDateTime.now();
/* ZonedDateTime 常用方法 */
// 获取时区信息
ZoneId zoneId = zonedDateTime.getZone();
// 转换为 LocalDate 对象
LocalDate localDate = zonedDateTime.toLocalDate();
// 转换为 LocalDateTime 对象
LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
// 转换为 OffsetDateTime 对象
OffsetDateTime offsetDateTime = zonedDateTime.toOffsetDateTime();
// 转换为 Instant 对象
Instant instant = zonedDateTime.toInstant();
// 指定年、月、日、时、分、秒参数获取日期时间实例
ZonedDateTime zonedDateTimeZone = ZonedDateTime.of(LocalDateTime.now(),ZoneId.of("GMT+8"));
// 指定年、月、日、时、分参数获取日期时间实例
ZonedDateTime ymdhmsnZonedDateTimeZone = ZonedDateTime.of(2020,6,18,12, 30,1,0,ZoneId.of("GMT+8"));
/* 输出 */
System.out.println("在默认时区中从系统时钟获取当前日期时间:" + zonedDateTime);
System.out.println("获取时区信息:" + zoneId);
System.out.println("转换为 LocalDate 对象:" + localDate);
System.out.println("转换为 LocalDateTime 对象:" + localDateTime);
System.out.println("转换为 OffsetDateTime 对象:" + offsetDateTime);
System.out.println("转换为 Instant 对象:" + instant);
System.out.println("指定年、月、日、时、分、秒参数获取日期时间实例:" + zonedDateTimeZone);
System.out.println("指定年、月、日、时、分、秒参数获取日期时间实例:" + ymdhmsnZonedDateTimeZone);
System.out.println("-------------------------------------------------");
}

public static void main(String[] args) {
// ZonedDateTime 转换
zoneTimeTransition();
}

}

输出如下:

1
2
3
4
5
6
7
8
9
10
11
## ZonedDateTime 转换
------------------------------------------------------------------------------------------
在默认时区中从系统时钟获取当前日期时间:2020-07-06T23:10:02.173+08:00[Asia/Shanghai]
获取时区信息:Asia/Shanghai
转换为 LocalDate 对象:2020-07-06
转换为 LocalDateTime 对象:2020-07-06T23:10:02.173
转换为 OffsetDateTime 对象:2020-07-06T23:10:02.173+08:00
转换为 Instant 对象:2020-07-06T15:10:02.173Z
指定年、月、日、时、分、秒参数获取日期时间实例:2020-07-06T23:10:02.173+08:00[GMT+08:00]
指定年、月、日、时、分、秒参数获取日期时间实例:2020-06-18T12:30:01+08:00[GMT+08:00]
------------------------------------------------------------------------------------------

8、Period

Period 主要用于获取时间度量值,可以获取两个日期的年、月、日的差值等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.time.LocalDate;
import java.time.Period;

public class PeriodExample {

/**
* 计算日期的差量
*/
public static void datePeriod() {
/* 创建两个日期对象 */
LocalDate localDate1 = LocalDate.of(2018, 6, 16);
LocalDate localDate2 = LocalDate.of(2020, 8, 18);
/* 获取由两个日期之间的年数、月数和天数组成的期间 */
Period period = Period.between(localDate1, localDate2);
/* 输出 */
System.out.println("年差量:" + period.getYears());
System.out.println("月差量:" + period.getMonths());
System.out.println("日差量:" + period.getDays());
System.out.println("-------------------------------------------------");
}

public static void main(String[] args) {
// 计算日期的差量
datePeriod();
}

}

输出如下:

1
2
3
4
5
6
## 计算日期的差量
------------
年差量:2
月差量:2
日差量:2
------------

9、ZoneId

主要用于创建 ZoneDateTime 时,指定时区选项,这里只介绍下如何创建 ZoneId 对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.time.OffsetDateTime;
import java.time.ZoneId;

public class ZoneIdExample {

/**
* 获取 ZoneId
*/
public static void getZoneId() {
/* 获取时区ID */
ZoneId zoneId = ZoneId.systemDefault();
// 从时区 ID 获取 ZoneId 的实例
ZoneId zoneIdOf = ZoneId.of("+08:00");
// 获取包含偏移量的 ZoneId 实例
ZoneId zoneIdOfOffset = ZoneId.ofOffset("GMT", OffsetDateTime.now().getOffset());
/* 输出 */
System.out.println("获取系统默认的时区:" + zoneId.getId());
System.out.println("获取此ID的时区规则以执行计算:" + zoneId.getRules());
System.out.println("从时区ID获取 ZoneId 的实例:" + zoneIdOf);
System.out.println("从时区ID获取 ZoneId 的实例:" + zoneIdOfOffset);
System.out.println("-------------------------------------------------");
}

public static void main(String[] args) {
// 获取 ZoneId
getZoneId();
}

}

输出如下:

1
2
3
4
5
6
7
## 获取 ZoneId
----------------------------------------------------------------------
获取系统默认的时区:Asia/Shanghai
获取此ID的时区规则以执行计算:ZoneRules[currentStandardOffset=+08:00]
从时区ID获取 ZoneId 的实例:+08:00
从时区ID获取 ZoneId 的实例:GMT+08:00
----------------------------------------------------------------------

10、ZoneOffset

表示时区偏移量,是 ZoneId 的子类,相对于格林尼治时间(GMT)的时间偏差,只是只处理与格林尼治的时间差;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.zone.ZoneRules;

public class ZoneOffsetExample {

/**
* 获取现在日期时间的时区偏移量
*/
public static void getNowZoneOffset(){
/* 获取 ZoneOffset 实例 */
ZoneOffset zoneOffsetNow = OffsetDateTime.now().getOffset();
/* 获取此偏移量相关时区的规则 */
ZoneRules zoneRules = zoneOffsetNow.getRules();
/* 输出 */
System.out.println("获取当前日期时间的【ZoneOffset】对象:" + zoneOffsetNow);
System.out.println("获取此偏移量相关时区的规则:" + zoneRules);
System.out.println("-------------------------------------------------");
}

/**
* 创建时区偏移量
*/
public static void createZoneOffset() {
/* 创建时区偏移量 */
// 使用【偏移量ID】获取【ZoneOffset】对象(最大支持的范围是从±18:00)
ZoneOffset zoneOffsetOf = ZoneOffset.of("+08:00");
// 使用以【秒】为【偏移量ID】获取【ZoneOffset】对象(最大支持的范围是从±64800)
ZoneOffset zoneOffsetSeconds = ZoneOffset.ofTotalSeconds(28800);
// 使用以【小时】为【偏移量ID】获取【ZoneOffset】对象(最大支持的范围是从±18)
ZoneOffset zoneOffsetByHours = ZoneOffset.ofHours(8);
// 使用以【小时和分钟】为【偏移量ID】获取【ZoneOffset】对象(小时最大支持的范围是从±18,分钟的范围为±59)
ZoneOffset zoneOffsetByHoursMinites = ZoneOffset.ofHoursMinutes(8, 30);
// 使用以【小时、分钟和秒】为【偏移量ID】获取【ZoneOffset】对象(小时最大支持的范围是从±18,分钟的范围为±59,秒的范围为±59)
ZoneOffset zoneOffsetByHoursMinutesSeconds = ZoneOffset.ofHoursMinutesSeconds(8, 30, 10);
/* 输出 */
System.out.println("使用【偏移量ID】获取【ZoneOffset】对象:" + zoneOffsetOf);
System.out.println("使用以【秒】为【偏移量ID】获取【ZoneOffset】对象:" + zoneOffsetSeconds);
System.out.println("使用以【小时】为【偏移量ID】获取【ZoneOffset】对象:" + zoneOffsetByHours);
System.out.println("使用以【小时与分钟】为【偏移量ID】获取【ZoneOffset】对象:" + zoneOffsetByHoursMinites);
System.out.println("使用以【小时、分钟和秒】为【偏移量ID】获取【ZoneOffset】对象:" + zoneOffsetByHoursMinutesSeconds);
System.out.println("-------------------------------------------------");
}

/**
* 时区偏移量比较
*/
public static void compareZoneOffset() {
/* 创建两个 ZoneOffset 实例 */
ZoneOffset zoneOffsetOf1 = ZoneOffset.of("+08:00");
ZoneOffset zoneOffsetOf2 = ZoneOffset.of("+09:00");
/* 时区偏移量比较 */
// 将此偏移量与另一个偏移量按降序比较(返回相差秒数)
int seconds = zoneOffsetOf1.compareTo(zoneOffsetOf2);
/* 输出 */
System.out.println("将此偏移量与另一个偏移量按降序比较:" + seconds);
System.out.println("-------------------------------------------------");
}

public static void main(String[] args) {
// 获取现在日期时间的时区偏移量
getNowZoneOffset();
// 创建时区偏移量
createZoneOffset();
// 时区偏移量比较
compareZoneOffset();
}

}

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
## 获取现在日期时间的时区偏移量
------------------------------------------------------------------------
获取当前日期时间的【ZoneOffset】对象:+08:00
获取此偏移量相关时区的规则:ZoneRules[currentStandardOffset=+08:00]
------------------------------------------------------------------------

## 创建时区偏移量
------------------------------------------------------------------------
使用【偏移量ID】获取【ZoneOffset】对象:+08:00
使用以【秒】为【偏移量ID】获取【ZoneOffset】对象:+08:00
使用以【小时】为【偏移量ID】获取【ZoneOffset】对象:+08:00
使用以【小时与分钟】为【偏移量ID】获取【ZoneOffset】对象:+08:30
使用以【小时、分钟和秒】为【偏移量ID】获取【ZoneOffset】对象:+08:30:10
------------------------------------------------------------------------

## 时区偏移量比较
------------------------------------------------------------------------
将此偏移量与另一个偏移量按降序比较:3600
------------------------------------------------------------------------

示例地址:
Java 8 新增的日期时间 API 使用示例

转自:http://www.mydlq.club/article/87