java8新特性专栏:https://blog.csdn.net/caoyuan666/category_11801993.html?spm=1001.2014.3001.5482
0.引言
为解决java8以前Date、Calendar等时间日期相关类线程不安全的问题(利用多线程对其进行更改时将报错),java8引入了更加方便完善的java.time。整体结构图如下所示。
1.LocalDate、LocalTime、LocalDateTime
根据需求,新的java.time提供了LocalDate、LocalTime、LocalDateTime分别表示日期、时间、日期+时间。他们的使用方法类似,这里仅以LocalDateTime举例
1.1 创建方式
创建一般有两种方式,通过now()获取当前时间,通过of()获取指定日期时间
- now() 从默认时区的系统时钟获取当前的日期时间。
- now(Clock clock) 从指定的时钟获取当前的日期时间。
- now(ZoneId zone) 从指定时区的系统时钟获取当前的日期时间。
LocalDateTime now1 = LocalDateTime.now();
LocalDateTime now2 = LocalDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println(now1);
System.out.println(now2);
2022-05-07T16:29:03.640
2022-05-07T17:29:03.640
- of(int year, int month, int dayOfMonth, int hour, int minute, int second)
of()有个重载的静态方法,详解开发手册
LocalDateTime dt1 = LocalDateTime.of(2022, 2, 2, 2, 20, 20);
System.out.println(dt1);
// 2022-02-02T02:20:20
1.2 常用方法
get方法用于获取响应数值
返回值类型 | 方法 | 描述 |
---|---|---|
int | get(TemporalField field) | 从此日期时间获取指定字段的值为 int |
int | getDayOfMonth() | 获取月份字段。 |
DayOfWeek | getDayOfWeek() | 获取星期几字段,这是一个枚举 DayOfWeek |
int | getDayOfYear() | 获得日期字段。 |
int | getHour() | 获取时间字段。 |
long | getLong(TemporalField field) | 从此日期时间获取指定字段的值为 long |
int | getMinute() | 获取小时字段。 |
Month | getMonth() | 使用 Month枚举获取月份字段。 |
int | getMonthValue() | 将月份字段从1到12。 |
int | getNano() | 获得纳秒第二场。 |
int | getSecond() | 获得第二分钟的字段。 |
int | getYear() | 获取年份字段。 |
比较方法
返回值类型 | 方法 | 描述 |
---|---|---|
boolean | isAfter(ChronoLocalDateTime<?> other) | 检查这个日期时间是否在指定的日期之后。 |
boolean | isBefore(ChronoLocalDateTime<?> other) | 检查此日期时间是否在指定的日期时间之前。 |
boolean | isEqual(ChronoLocalDateTime<?> other) | 检查此日期时间是否等于指定的日期时间。 |
加减方法:用于根据响应单位处理
- plusxxx(),如plusSeconds(long seconds)
- minusxxx(),如minusHours(long hours)
2.格式化解析
DateTimeFormatter :主要用于日期时间 & String之间的解析与格式化
扫描二维码关注公众号,回复:
14761775 查看本文章
LocalDateTime ldt = LocalDateTime.of(1997, 1, 1, 10, 10);
String s = ldt.toString();
System.out.println(s);
// 1.自定义格式化&解析
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yy:MM:dd===HH:mm:ss");
String format = ldt.format(dtf);
String format1 = dtf.format(ldt);
System.out.println(format);
System.out.println(format1);
TemporalAccessor parse = dtf.parse(format);
System.out.println(parse.getClass());
LocalDateTime parse1 = LocalDateTime.parse(format1, dtf);
System.out.println(parse);
System.out.println(parse1);
System.out.println("-----------------");
// 2.ISO_LOCAL_DATE标准格式化
DateTimeFormatter isoDateTime = DateTimeFormatter.ISO_LOCAL_DATE;
LocalDate ld = LocalDate.now();
String format2 = ld.format(isoDateTime);
System.out.println(format2);
System.out.println("-----------------");
// 3.时间格式化
LocalTime now = LocalTime.now();
DateTimeFormatter isoLocalTime = DateTimeFormatter.ISO_LOCAL_TIME;
System.out.println(now.format(isoLocalTime));
1997-01-01T10:10
97:01:01===10:10:00
97:01:01===10:10:00
class java.time.format.Parsed
{},ISO resolved to 2097-01-01T10:10
2097-01-01T10:10
-----------------
2022-05-07
-----------------
17:02:38.774
Process finished with exit code 0
3.时区
- ZoneId:时区ID
- ZoneOfferset:时区补偿
LocalDateTime now1 = LocalDateTime.now();
LocalDateTime now2 = LocalDateTime.now(ZoneId.of("Australia/Sydney"));
System.out.println(now1);
System.out.println(now2);
System.out.println(ZoneOffset.UTC);
System.out.println(ZoneOffset.ofHours(8));
2022-05-07T19:01:35.412
2022-05-07T21:01:35.414
Z
+08:00
4.时间戳
- 时间戳:以Unix元年:1970年1月1日 00:00:00 到某个时间的毫秒值
- UTC时间:子午线所在时区的基准时间,时间戳获取的默认时区
- 与LocalDateTime转换,注意时区,我国为东8区
Instant now = Instant.now();
long epochSecond = now.getEpochSecond();
Instant instant1 = Instant.ofEpochSecond(epochSecond);
System.out.println(now);
System.out.println(epochSecond);
System.out.println(instant1);
System.out.println("-------------");
// LocalDateTime & Instant 转换
LocalDateTime dateTime = LocalDateTime.ofInstant(now, ZoneId.of("Asia/Shanghai"));
LocalDateTime dateTime1 = LocalDateTime.ofInstant(now, ZoneId.systemDefault());
Instant instant = dateTime.toInstant(ZoneOffset.ofHours(8));
System.out.println(dateTime);
System.out.println(dateTime1);
System.out.println(instant);
2022-05-07T10:59:34.371Z
1651921174
2022-05-07T10:59:34Z
-------------
2022-05-07T18:59:34.371
2022-05-07T18:59:34.371
2022-05-07T10:59:34.371Z
Process finished with exit code 0
5.间隔
- 时间之前:Duration
- 日期之间:Period
获取两个点之间的间隔,可转换为需要显示的时间单位:
- getXXX():如getSeconds()
- toXXX():如toMillis()
LocalDateTime start = LocalDateTime.now();
Thread.sleep(1000);
LocalDateTime end = LocalDateTime.now();
System.out.println(Duration.between(start, end).getSeconds());
System.out.println(Duration.between(start, end).toMillis());
1
1002
6.时间调节器
使用TemporalAdjust调整日期,找到下一个所需日期
- TemporalAdjuster:函数式接口,如下所示,可以自己实现
- TemporalAdjusters:实现TemporalAdjuster接口的工具类,提供了常用方法
@FunctionalInterface
public interface TemporalAdjuster {
Temporal adjustInto(Temporal temporal);
}
示例操作:
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
System.out.println(now.getDayOfWeek());
System.out.println(now.withDayOfMonth(1));
System.out.println(now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)));
System.out.println(now.with(TemporalAdjusters.firstDayOfNextMonth()));
// 找下一个工作日
LocalDateTime nextDate = now.with((obj) -> {
LocalDateTime date = (LocalDateTime) obj;
DayOfWeek dayOfWeek = date.getDayOfWeek();
if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
return date.plusDays(3);
} else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
return date.plusDays(2);
} else {
return date.plusDays(1);
}
});
System.out.println(nextDate);
2022-05-07T19:31:33.665
SATURDAY
2022-05-01T19:31:33.665
2022-05-08T19:31:33.665
2022-06-01T19:31:33.665
2022-05-09T19:31:33.665