上篇说了JDK7的Calendar以及SimpleDateFormat等相关日期类,其实最好还是使用JDK8中的日期类,安全且支持更加丰富。

JDK7和8日期类比较

JDK8新增的日期类分得更细致一些,比如表示年月日用LocalDate类、表示时间秒用LocalTime类、而表示年月日时分秒用LocalDateTime类等;除了这些类还提供了对时区、时间间隔进行操作的类等,用起来特别方便。

image-20240127172344465

详细说明

image-20240127173048482

JDK8日期

Notes: 这里part1,2,3,4是上图中的四大模块。

PART1

LocalDate、LocalTime、以及LocalDateTime类。这三个类的用法基本大同小异,由于我之前偷懒就写了一个Demo,这里就copy一下别人的代码。

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
public class Test1_LocalDate {
public static void main(String[] args) {
// 0、获取本地日期对象(不可变对象)
LocalDate ld = LocalDate.now(); // 年 月 日
System.out.println(ld);

// 1、获取日期对象中的信息
int year = ld.getYear(); // 年
int month = ld.getMonthValue(); // 月(1-12)
int day = ld.getDayOfMonth(); // 日
int dayOfYear = ld.getDayOfYear(); // 一年中的第几天
int dayOfWeek = ld.getDayOfWeek().getValue(); // 星期几
System.out.println(year);
System.out.println(day);
System.out.println(dayOfWeek);

// 2、直接修改某个信息: withYear、withMonth、withDayOfMonth、withDayOfYear
LocalDate ld2 = ld.withYear(2099);
LocalDate ld3 = ld.withMonth(12);
System.out.println(ld2);
System.out.println(ld3);
System.out.println(ld);

// 3、把某个信息加多少: plusYears、plusMonths、plusDays、plusWeeks
LocalDate ld4 = ld.plusYears(2);
LocalDate ld5 = ld.plusMonths(2);

// 4、把某个信息减多少:minusYears、minusMonths、minusDays、minusWeeks
LocalDate ld6 = ld.minusYears(2);
LocalDate ld7 = ld.minusMonths(2);

// 5、获取指定日期的LocalDate对象: public static LocalDate of(int year, int month, int dayOfMonth)
LocalDate ld8 = LocalDate.of(2099, 12, 12);
LocalDate ld9 = LocalDate.of(2099, 12, 12);

// 6、判断2个日期对象,是否相等,在前还是在后: equals isBefore isAfter
System.out.println(ld8.equals(ld9));// true
System.out.println(ld8.isAfter(ld)); // true
System.out.println(ld8.isBefore(ld)); // false
}
}

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
public class Test2_LocalTime {
public static void main(String[] args) {
// 0、获取本地时间对象
LocalTime lt = LocalTime.now(); // 时 分 秒 纳秒 不可变的
System.out.println(lt);

// 1、获取时间中的信息
int hour = lt.getHour(); //时
int minute = lt.getMinute(); //分
int second = lt.getSecond(); //秒
int nano = lt.getNano(); //纳秒

// 2、修改时间:withHour、withMinute、withSecond、withNano
LocalTime lt3 = lt.withHour(10);
LocalTime lt4 = lt.withMinute(10);
LocalTime lt5 = lt.withSecond(10);
LocalTime lt6 = lt.withNano(10);

// 3、加多少:plusHours、plusMinutes、plusSeconds、plusNanos
LocalTime lt7 = lt.plusHours(10);
LocalTime lt8 = lt.plusMinutes(10);
LocalTime lt9 = lt.plusSeconds(10);
LocalTime lt10 = lt.plusNanos(10);

// 4、减多少:minusHours、minusMinutes、minusSeconds、minusNanos
LocalTime lt11 = lt.minusHours(10);
LocalTime lt12 = lt.minusMinutes(10);
LocalTime lt13 = lt.minusSeconds(10);
LocalTime lt14 = lt.minusNanos(10);

// 5、获取指定时间的LocalTime对象:
// public static LocalTime of(int hour, int minute, int second)
LocalTime lt15 = LocalTime.of(12, 12, 12);
LocalTime lt16 = LocalTime.of(12, 12, 12);

// 6、判断2个时间对象,是否相等,在前还是在后: equals isBefore isAfter
System.out.println(lt15.equals(lt16)); // true
System.out.println(lt15.isAfter(lt)); // false
System.out.println(lt15.isBefore(lt)); // true

}
}

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
public class Test3_LocalDateTime {
public static void main(String[] args) {
// 0、获取本地日期和时间对象。
LocalDateTime ldt = LocalDateTime.now(); // 年 月 日 时 分 秒 纳秒
System.out.println(ldt);

// 1、可以获取日期和时间的全部信息
int year = ldt.getYear(); // 年
int month = ldt.getMonthValue(); // 月
int day = ldt.getDayOfMonth(); // 日
int dayOfYear = ldt.getDayOfYear(); // 一年中的第几天
int dayOfWeek = ldt.getDayOfWeek().getValue(); // 获取是周几
int hour = ldt.getHour(); //时
int minute = ldt.getMinute(); //分
int second = ldt.getSecond(); //秒
int nano = ldt.getNano(); //纳秒

// 2、修改时间信息:
// withYear withMonth withDayOfMonth withDayOfYear withHour
// withMinute withSecond withNano
LocalDateTime ldt2 = ldt.withYear(2029);
LocalDateTime ldt3 = ldt.withMinute(59);

// 3、加多少:
// plusYears plusMonths plusDays plusWeeks plusHours plusMinutes plusSeconds plusNanos
LocalDateTime ldt4 = ldt.plusYears(2);
LocalDateTime ldt5 = ldt.plusMinutes(3);

// 4、减多少:
// minusDays minusYears minusMonths minusWeeks minusHours minusMinutes minusSeconds minusNanos
LocalDateTime ldt6 = ldt.minusYears(2);
LocalDateTime ldt7 = ldt.minusMinutes(3);


// 5、获取指定日期和时间的LocalDateTime对象:
// public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour,
// int minute, int second, int nanoOfSecond)
LocalDateTime ldt8 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222);
LocalDateTime ldt9 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222);

// 6、 判断2个日期、时间对象,是否相等,在前还是在后: equals、isBefore、isAfter
System.out.println(ldt9.equals(ldt8));
System.out.println(ldt9.isAfter(ldt));
System.out.println(ldt9.isBefore(ldt));

// 7、可以把LocalDateTime转换成LocalDate和LocalTime
// public LocalDate toLocalDate()
// public LocalTime toLocalTime()
// public static LocalDateTime of(LocalDate date, LocalTime time)
LocalDate ld = ldt.toLocalDate();
LocalTime lt = ldt.toLocalTime();
LocalDateTime ldt10 = LocalDateTime.of(ld, lt);

}
}

ZoneId时区

概述

1
表示时区对象;

获取方法

1
2
3
利用静态方法 of(字符串时区); 获取指定时区对象
利用静态方法 systemDefault();获取当前系统默认时区对象
利用静态方法 getAvailableZoneIds();获取当前系统支持的所有时区对象

应用场景

1
把时区对象,当成 ZoneDateTime的参数,获取一个带时区的日期对象;

代码案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class MyZoneDate {
public static void main(String[] args) {
// 1, 获取系统默认的时区对象
System.out.println(ZoneId.systemDefault());

// 2, 查询所有支持的时区
System.out.println(ZoneId.getAvailableZoneIds());

// 3, 根据名称获取时区对象
ZoneId of = ZoneId.of("America/New_York");
System.out.println(of);

// 4, 获取带时区的日期对象
System.out.println(ZonedDateTime.now());
System.out.println(ZonedDateTime.now(of));

// 5,获取,修改,推移时间信息 参考LocalDateTime
System.out.println(ZonedDateTime.now(of).getDayOfMonth());
}
}

PART2(Instant)

通过获取Instant的对象可以拿到此刻的时间,该时间由两部分组成:从1970-01-01 00:00:00 开始走到此刻的总秒数+不够1秒的纳秒数。

概述

1
用于表示时间戳的日期对象,可以精确到纳秒;

获取方法

1
利用静态方法 now(); 

常用方法

image-20240127180026656

代码案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.time.Instant;

/*
时间戳对象:可以精确到纳秒
*/
public class MyInstant {
public static void main(String[] args) {
// 1, 利用静态方法获取对象
Instant now = Instant.now();
System.out.println(now);
// 2, 获取总描述
System.out.println(now.getEpochSecond());
System.out.println(System.currentTimeMillis());

// 3, 时间推移
Instant instant = now.plusSeconds(-30);
System.out.println(instant);
}
}

PART3(DateTimeFormatter)

概述

1
是jdk8提供的日期格式化的工具类,可以当成日期格式化和解析日期时候的参数使用;

获取方式

1
静态方法: ofPattern("模式字符串");

解析和格式化的方法

  1. 解析,使用 日期类(LocalDateTime)中的静态方法 parse,传递要解析的字符串和格式化工具对象;
  2. 格式化,使用 日期对象 format(格式化工具对象);

image-20240127180726137

代码案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
思想转变:以日期类或日期对象为主导地位,以工具对象为辅助地位
*/
public class MyDateTimeFormatter {
public static void main(String[] args) {
// 1, 获取一个工具对象
DateTimeFormatter sf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 2, 获取当前时间对象
LocalDateTime now = LocalDateTime.now();
// 3, 格式化
System.out.println(now.format(sf));
// 4, 解析
LocalDateTime dt = LocalDateTime.parse("2021-01-01 11:11:11", sf);
System.out.println(dt);
}
}

PART4(Period&Duration)

概述

1
把一个时间段看成了对象,让程序员可以面向这个时间段操作;

分类

Period: 粗粒度间隔对象

Duration: 细粒度间隔对象

获取方式

利用静态方法 between(两个时间对象)

注意事项

Period能操作只能操作LocalDate;

Duration只能操作带毫秒的时间对象;(除了LocalDate之外的时间对象)

常用方法

  1. getXxx(); 获取信息或 toXxx()获取信息
  2. Period

image-20240127180813814

  1. Duration

image-20240127180851302

Period代码案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class PeriodTest {
public static void main(String[] args) {
// 1, 获取两个时间对象
LocalDate now = LocalDate.now();
LocalDate of = LocalDate.of(2024, 1, 9);
// 2, 利用静态对象获取时间间隔
Period between = Period.between(of, now);
// 3, 面向间隔时间对象,获取信息
System.out.println(between.getYears());
System.out.println(between.getMonths());
System.out.println(between.getDays());
System.out.println(between.toTotalMonths());
}
}

Duration代码案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
概述:把一个时间段看成对象,让程序员可以面向这个时间段操作
Period:粗粒度间隔对象
Duration:细粒度间隔对象
Tips:
Period 能且只能操作LocalDate
Duration 只能操作带毫秒的时间对象,除了LocalDate之外的时间对象
*/
public class DurationTest {
public static void main(String[] args) {
// 1, 获取两个时间对象
LocalDateTime now = LocalDateTime.now();
LocalDateTime of = LocalDateTime.of(2024, 1, 25, 01, 02, 03);
// 2, 利用静态方法获取间隔对象
Duration between = Duration.between(of, now);
// 3, 获取间隔时间
System.out.println(between.toDays());
System.out.println(between.toHours());
}
}