时间

LocalDate,LocalTime,LocalDateTime

获取时间

1
2
3
4
5
6
7
import java.time.*
LocalDateTime dt= LocalDateTime.now();//2021-07-14T09:53:41.095
LocalDate d = dt.toLocalDate()//2021-07-14
LocalTime t = dt.toLocalTime()//09:53:41.095

LocalDate d1 = LocalDate.now()//2021-07-14
LocalTime t1 = LocalTime.now()//09:53:41.095

设置时间

1
2
3
4
5
// 指定日期和时间:
LocalDate d2 = LocalDate.of(2019, 11, 30); // 2019-11-30, 注意11=11月
LocalTime t2 = LocalTime.of(15, 16, 17); // 15:16:17
LocalDateTime dt2 = LocalDateTime.of(2019, 11, 30, 15, 16, 17);
LocalDateTime dt3 = LocalDateTime.of(d2, t2);

将字符串转换为时间

1
2
3
LocalDateTime dt = LocalDateTime.parse("2019-11-19T15:16:17");
LocalDate d = LocalDate.parse("2019-11-19");
LocalTime t = LocalTime.parse("15:16:17");

LocalDateTimeLocalDateLocalTime默认严格按照ISO 8601规定的日期和时间格式进行打印。

ISO 8601规定的日期和时间分隔符是T。标准格式如下:

  • 日期:yyyy-MM-dd
  • 时间:HH:mm:ss
  • 带毫秒的时间:HH:mm:ss.SSS
  • 日期和时间:yyyy-MM-dd’T’HH:mm:ss
  • 带毫秒的日期和时间:yyyy-MM-dd’T’HH:mm:ss.SSS

DateTimeFormatter

如果要自定义输出的格式,或者要把一个非ISO 8601格式的字符串解析成LocalDateTime,可以使用新的DateTimeFormatter

1
2
3
4
5
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
System.out.println(dtf.format(LocalDateTime.now()));//2021/07/14 02:04:19
// 用自定义格式解析:
LocalDateTime dt2 = LocalDateTime.parse("2036/1/28 15:56:47", dtf);
System.out.println(dt2);//2036-1-28T15:56:47

时间上的加减运算

1
2
3
4
5
6
7
8
LocalDateTime dt = LocalDateTime.of(2019, 10, 26, 20, 30, 59);
System.out.println(dt);
// 加5天减3小时:
LocalDateTime dt2 = dt.plusDays(5).minusHours(3);
System.out.println(dt2); // 2019-10-31T17:30:59
// 减1月:
LocalDateTime dt3 = dt2.minusMonths(1);
System.out.println(dt3); // 2019-09-30T17:30:59

月份加减会自动调整日期,例如从2019-10-31减去1个月得到的结果是2019-09-30,因为9月没有31日。

修改时间

  • 调整年:withYear()
  • 调整月:withMonth()
  • 调整日:withDayOfMonth()
  • 调整时:withHour()
  • 调整分:withMinute()
  • 调整秒:withSecond()
1
2
3
4
5
6
7
8
LocalDateTime dt = LocalDateTime.of(2019, 10, 26, 20, 30, 59);
System.out.println(dt);
// 日期变为31日:
LocalDateTime dt2 = dt.withDayOfMonth(31);
System.out.println(dt2); // 2019-10-31T20:30:59
// 月份变为9:
LocalDateTime dt3 = dt2.withMonth(9);
System.out.println(dt3); // 2019-09-30T20:30:59

注意到调整月份时,会相应地调整日期,即把2019-10-31的月份调整为9时,日期也自动变为30

LocalDateTime还有一个通用的with()方法允许我们做更复杂的运算。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 本月第一天0:00时刻:
LocalDateTime firstDay = LocalDate.now().withDayOfMonth(1).atStartOfDay();
System.out.println(firstDay);

// 本月最后1天:
LocalDate lastDay = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
System.out.println(lastDay);

// 下月第1天:
LocalDate nextMonthFirstDay = LocalDate.now().with(TemporalAdjusters.firstDayOfNextMonth());
System.out.println(nextMonthFirstDay);

// 本月第1个周一:
LocalDate firstWeekday = LocalDate.now().with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
System.out.println(firstWeekday);


输出:
2021-07-01T00:00
2021-07-31
2021-08-01
2021-07-05

判断两个日期/时间的先后

isBefore()isAfter()

1
2
3
4
5
6
7
8
9
10
LocalDateTime now = LocalDateTime.now();
LocalDateTime target = LocalDateTime.of(2019, 11, 19, 8, 15, 0);
System.out.println(now.isBefore(target));
System.out.println(LocalDate.now().isBefore(LocalDate.of(2019, 11, 19))); System.out.println(LocalTime.now().isAfter(LocalTime.parse("08:15:00")));

输出:
false
false
false

计算两个日期/时间之间的间隔

Duration表示两个时刻之间的时间间隔。另一个类似的Period表示两个日期之间的天数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
LocalDateTime start = LocalDateTime.of(2019, 11, 19, 8, 15, 0);
LocalDateTime end = LocalDateTime.of(2020, 1, 9, 19, 25, 30);
Duration d = Duration.between(start, end);
System.out.println(d); // PT1235H10M30S
Period p = LocalDate.of(2019, 11, 19).until(LocalDate.of(2020, 1, 9));
System.out.println(p); // P1M21D
Duration tt = Duration.between(start.toLocalTime(),end.toLocalTime());
System.out.println(tt);//PT11H10M30S

输出:
PT1235H10M30S
P1M21D
PT11H10M30S


LocalDateTime dtt = start.plus(d5);
System.out.println(dtt);//2020-01-09T19:25:30

DurationPeriod的表示方法也符合ISO 8601的格式,它以P...T...的形式表示,P...T之间表示日期间隔,T后面表示时间间隔。如果是PT...的格式表示仅有时间间隔。利用ofXxx()或者parse()方法也可以直接创建Duration

1
2
3
4
5
6
Duration d1 = Duration.ofHours(10); // 即10 hours
Duration d2 = Duration.parse("P1DT2H3M"); // 即1 day, 2 hours, 3 minutes

输出:
PT10H
PT26H3M