时间类

java.util.Date 设定为可变类型,以及 SimpleDateFormat 的非线程安全使其应用非常受限。之后就在 Java8 上添加了新特性。

java.time中所有的类都是不可变对象。

  • Instant: 瞬时实例/时间戳。
  • LocalDate: 本地日期,不含具体时间。
  • LocalTime: 本地时间,不含具体日期。
  • LocalDateTime: 组合日期和时间,不包含时差和时间。
  • ZoneDateTime: 最完整的日期和时间。包含时区和相对于UTC的时差。
  • ZoneOffSet/ZoneId: 更为简单的操作时区。
  • DateTimeFormatter: 全新的时间格式化和解析类。
  • Year/Month: 只存储年月信息。
  • MonthDay/YearMonth: 记录年月/月日,用来指定特殊日期(如纪念日,到期月份)。
  • Clock: 获取当时的时间戳,或当前时区下的日期时间信息。
  • Period/Duration: 记录一段时间段,例如两个实例之间的时间差。

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
// 创建实例
LocalDate date = LocalDate.of(2020, 10, 1); // 通过of方法创建LocalDate实例
LocalDate tempDate = LocalDate.now(); // 通过now()方法获取当前时间
LocalDate date = LocalDate.from(LocalDateTime.now()); // 从更具体的时间中获取
// 获取信息
System.out.println(date.getYear()); // 通过get方法获取当前年份等基本信息
System.out.println(date.getDayOfYear()); // 可以通过getDayOf方法获取一些更高级的信息。
System.out.println(date.lengthOfYear()); // 获取年份或者月份的天数
// 判断信息
System.out.println(date.isAfter(tempDate)); // 比较两个时间
System.out.println(date.isLeapYear()); // 判断是否为闰年
System.out.println(date.isEqual(tempDate)); // 判断两个时间是否相同
System.out.println(date.isSupported(ChronoField.SECOND_OF_DAY)); // 判断实例是否支持某单位(false ,因为LocalDate不支持时间)
// 计算日期
System.out.println(date.minus(1, ChronoUnit.DAYS)); // 指定单位计算
System.out.println(date.minusDays(1)); // 快捷计算日期
System.out.println(date.plusMonths(1));
// 更改日期信息
System.out.println(date.with(ChronoField.DAY_OF_YEAR, 45)); // 指定单位更改
System.out.println(date.withYear(2000)); // 指定字段更改
System.out.println(date.with(MonthDay.now())); // 通过部分时间更改
// 格式化时间
System.out.println(date.format(DateTimeFormatter.ofPattern("yyyy MM dd"))); // 给定格式格式化时间字符串
System.out.println(date.format(DateTimeFormatter.ISO_DATE)); // 使用内置的时间格式格式化时间
// 解析时间
LocalDate.parse("20201001", DateTimeFormatter.ofPattern("yyyyMMdd"));
// 转换类
System.out.println(date.atStartOfDay()); // 设置时间为0时整(返回的是LocalDateTime对象)
System.out.println(date.atTime(1,1,1)); // 设置时间为指定时间

LocalTime

1
2
3
4
LocalTime time = LocalTime.now();
LocalTime time = LocalTime.of(12, 12, 12);
time.withNano(12); // 最多支持到纳秒 (12:12:12.000000012)
// 大多数操作与LocalDateTime类似。例如在获取一天中的秒数。或者计算时间。

LocalDateTime

1
2
3
LocalDateTime dateTime = LocalDateTime.now();
dateTime.toInstant(ZoneOffset.UTC); // 将LocalDateTime转换为时间戳
System.out.println(dateTime.toLocalDate()); // 转换为LocalDate

Year/Month

1
2
3
4
5
6
7
// 创建实例
Year year = Year.now();
Year year = Year.of(2000);
Year year = Year.from(date);
Month month = Month.of(1);
Month month = date.getMonth();
// 也可以通过 at 方法来指定更具体的对象。增减,比较等方法依旧可用。

YearMonth/MonthDay

1
2
3
4
5
// 创建实例
YearMonth yearMonth = YearMonth.now();
YearMonth yearMonth = YearMonth.of(2000, 10);
YearMonth yearMonth = YearMonth.from(date);
// 同样可以使用 at 方法指定等具体的时间,用 with 方法更改时间,也可以使用增减、判断和获取等方法。

Clock/Instant

1
2
3
4
5
6
7
8
9
10
11
12
// 创建实例
Clock clock = Clock.systemUTC(); // 获取UTC的时间戳
Clock clock = Clock.systemDefaultZone(); // 获取系统默认时区时间戳
// 更改时区
clock.withZone(ZoneId.of("Asia/Shanghai"));
// 获取信息
clock.millis(); // 获取毫秒数
clock.instant(); // 获取瞬时实例
// 创建实例
Instant instant = Instant.now();
Instant instant = Instant.ofEpochMilli(1603380890080L); // 从世纪纪元毫秒或秒中获取。
// 同样可以使用 at 方法指定等具体的时间,用 with 方法更改时间,也可以使用增减、判断和获取等方法。一般只能处理与秒即相关的。

ZoneId/ZoneOffSet

1
2
3
4
5
6
7
8
// 创建实例
ZoneId zoneId = ZoneId.systemDefault(); // ZoneId记录了时区缩写和简写
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
ZoneOffset zoneOffset = ZoneOffset.of("+5"); // ZoneOffSet 指定与UTC时区的相对时间差
ZoneOffset zoneOffset = ZoneOffset.of("+05:30:30");
// 获取信息
zoneId.getRules(); // 获取Rules:ZoneRules[currentStandardOffset=+08:00]
zoneOffset.getTotalSeconds(); // 获取相较于UTC总共的时间差

ZonedDateTime

1
2
3
4
5
6
7
8
// 创建实例
ZonedDateTime zonedDateTime = ZonedDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.of(2020,10,01,0,0,0,0,ZoneId.of("Asia/Shanghai"));
ZonedDateTime zonedDateTime = ZonedDateTime.of(2020,10,01,0,0,0,0,ZoneOffset.of("+8"));
// 更改时区
zonedDateTime.withZoneSameLocal(ZoneId.of("Z")); // 更改时区,但不变更时间
zonedDateTime.withZoneSameInstant(ZoneId.of("Z")); // 更改时区,并根据变更的时区变更时间
// ZoneDateTime是最全面的时间类,之前所有类含有的方法,ZoneDateTime一般都可以使用。

Period/Duration

1
2
3
4
5
6
7
8
9
10
11
// Period 主要记录的是关于天数以上的时间段
LocalDate date = LocalDate.now();
LocalDate date1 = LocalDate.of(2000,11,1);
Period period = Period.between(date, date1)
System.out.println(period); // P-19Y-11M-22D

LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime localDateTime1 = LocalDateTime.of(2018, 1, 1, 1, 0);
System.out.println(Duration.between(localDateTime, localDateTime1)); // PT-24646H-23M-36.618S

// 同样可以使用 with 方法来更改日期,也可以使用增减和判断的方法。同样可以使用 to 方法转换为其他时间