预览
学习原因
- jdk8之前既然已经有了相关的处理类,为什么还要新增这些类呢?
设计不合理
- 比如说Date.getYear 返回的2024-1900的时间差=124年
- Calendar.set(Calendar.YEAR, 2020); 我们是需要记忆对应的字段名称的
- 都是修改源对象,而不是返回新对象
- 一旦修改,就找不到
源对象的信息
新老API的替代关系
LocalDate、LocalTime、LocalDateTime
- 他们获取对象的方式:非构造器,是使用now方法获取实例对象
LocalDate
相关的获取方法(更加合理)
// jdk1.8之后的日期 LocalDate 获取当前日期 指的是年月日
LocalDate localDate = LocalDate.now(); // 使用now方法获取实例
int year = localDate.getYear(); // 获取年 2024(原本是2024 - 1900)
int month = localDate.getMonthValue(); // 获取月 1-12(原本是0-11)
int day = localDate.getDayOfMonth(); // 获取日 1-31
int dayOfYear = localDate.getDayOfYear(); // 获取年的第几天 1-365
DayOfWeek dayOfWeek = localDate.getDayOfWeek(); // 获取星期几
int dayOfWeekValue = dayOfWeek.getValue(); // 获取星期几的值 1-7
int lengthOfMonth = localDate.lengthOfMonth(); // 获取这个月有多少天
- jdk之后的日期对象都是不可修改的对象
- 修改:会返回一个新的对象,
不会修改原本的对象
// 设置年月日
LocalDate localDate1 = localDate.withMonth(2); // 设置月份
LocalDate localDate2 = localDate.withYear(2020); // 设置年份
LocalDate localDate3 = localDate.withDayOfMonth(1); // 设置日
LocalDate localDate4 = localDate.withDayOfYear(1); // 设置年的第几天
在原有的基础上增加(加是plus,减是minus)
// 增加年月日
LocalDate localDate5 = localDate.plusYears(1); // 增加年
LocalDate localDate6 = localDate.plusMonths(1); // 增加月
LocalDate localDate7 = localDate.plusDays(1); // 增加日
LocalDate localDate8 = localDate.plusWeeks(1); // 增加周
判断日期是否相等
// 判断日期大小 isEqual isBefore isAfter
boolean flag = localDate.isAfter(localDate1); // 判断日期是否在指定日期之后
boolean flag1 = localDate.isBefore(localDate1); // 判断日期是否在指定日期之前
boolean flag2 = localDate.isEqual(localDate); // 判断日期是否等于指定日期
LocalTime
这个类的方法和LocalDate的方法一模一样
获取
// jdk1.8之后的时间 LocalTime 获取当前时间 指的是时分秒
LocalTime localTime = LocalTime.now(); // 获取当前时间
// 获取指定时间的对象
LocalTime localTime9 = LocalTime.of(1, 1, 1); // 01:01:01
设置
// 设置时分秒
LocalTime localTime1 = localTime.withHour(1); // 设置小时
LocalTime localTime2 = localTime.withMinute(1); // 设置分钟
LocalTime localTime3 = localTime.withSecond(1); // 设置秒
LocalTime localTime4 = localTime.withNano(1); // 设置纳秒
// 增加时分秒
LocalTime localTime5 = localTime.plusHours(1); // 增加小时
LocalTime localTime6 = localTime.plusMinutes(1); // 增加分钟
LocalTime localTime7 = localTime.plusSeconds(1); // 增加秒
LocalTime localTime8 = localTime.plusNanos(1); // 增加纳秒
判断
// 判断时间大小 equal isBefore isAfter
boolean flag = localTime.isAfter(localTime1); // 判断时间是否在指定时间之后
boolean flag1 = localTime.isBefore(localTime1); // 判断时间是否在指定时间之前
boolean flag2 = localTime.equals(localTime.plusHours(1).minusHours(1)); // 判断时间是否等于指定时间
LocalDateTime
- 这是上面两个类的
结合体
,上面两个类有的方法他都有- 新增一个
结合
方法:将LocalDate 和 LocalTime 结合成 LocalDateTime- 新增两个
拆分
方法
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
//结合日期和时间
LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
//拆分日期和时间
LocalDate date = localDateTime.toLocalDate();
LocalTime time = localDateTime.toLocalTime();
ZoneId
- 时区类:弥补了早期设计的时候忘记考虑不同时区之间存在
时区差
的问题- 作用:
- 通过传入不同时区,获得
不同时区的当前时间
- 也可以通过此类完成
不同时区的时间转换
ZoneId zoneId = ZoneId.systemDefault(); // 获取系统默认时区
System.out.println(zoneId); // Asia/Shanghai
System.out.println(zoneId.getId()); // Asia/Shanghai
System.out.println(zoneId.getRules()); // ZoneRules[currentStandardOffset=+08:00]
// 获取所有时区
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
// availableZoneIds.forEach(System.out::println);
// 获取指定时区
ZoneId zoneId1 = ZoneId.of("America/New_York");
// 使用指定时区获取对应时区的当前时间
ZoneId zoneId2 = ZoneId.of("America/New_York");
// 中国时间 2024-04-08T09:24:43.178
// 美国时间 2024-04-07T21:24:43.178
System.out.println(LocalDateTime.now(zoneId2));
// 获取格林威治时间
ZoneId zoneId3 = ZoneId.of("GMT");
System.out.println(LocalDateTime.now(zoneId3)); // 2024-04-08T01:24:43.178
//当然ZoneId也有很多关于时间的操作方法,凡是LocalDateTime有的它都有,这里就不一一列举了
Instant
- 原因:传统的时间对象只到了毫秒,且是可变对象
- 返回新对象意味着支持链式编程
- 这个对象很适合
不会重复的文件名之类的东西
获取
// jdk1.8之后的时间戳 Instant
Instant instant = Instant.now();
// 获取秒 从1970年1月1日 00:00:00开始计算
long epochSecond = instant.getEpochSecond(); // 1712540608
// 获取毫秒 从1970年1月1日 00:00:00开始计算
long toEpochMilli = instant.toEpochMilli(); // 1712540608000
// 获取纳秒 这里指的是不够1秒的纳秒数 0-999999999
int nano = instant.getNano(); // 497000000
加减
// 秒、毫秒、纳秒的加
Instant instant1 = instant.plusSeconds(1);
Instant instant2 = instant.plusMillis(1);
Instant instant3 = instant.plusNanos(1);
判断
// 判断
boolean flag = instant.isAfter(instant1);
boolean flag1 = instant.isBefore(instant1);
boolean flag2 = instant.equals(instant.plusSeconds(1).minusSeconds(1));
DateTimeFormatter
作用:新的格式化类是线程安全的,不同线程是可以同事操作一个时间对象的
// jdk1.8之后的时间格式化 DateTimeFormatter
// DateTimeFormatter 是线程安全
// ofPattern方法创建DateTimeFormatter对象
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
不管是格式化还是解析,都提供了两种方法:
- 以
DateTimeFormatter
为主体- 以要
转换的对象
类型为主体
格式化
// 格式化方式1:调用DateTimeFormatter的format方法
String dateStr = dateTimeFormatter.format(LocalDateTime.now());
// 格式化方式2:调用LocalDateTime的format方法
String dateStr1 = LocalDateTime.now().format(dateTimeFormatter);
解析
// 解析方式1:调用DateTimeFormatter的parse方法,再调用对应类型的from方法
// 解析时间
TemporalAccessor temporalAccessor = dateTimeFormatter.parse(dateStr);
// 转换
LocalDateTime localDateTime = LocalDateTime.from(temporalAccessor);
System.out.println(localDateTime);
// 解析方式2:直接调用对应类型的parse方法
LocalDateTime parse = LocalDateTime.parse(dateStr, dateTimeFormatter);
System.out.println(parse);
Period
- Period :计算的两个日期之间的间隔,不能计算相差的时间之间的间隔
- 所有传递的
参数是LocalDate
// jdk1.8之后的时间间隔 Period
// 用于计算两个日期LocalDate之间的间隔
LocalDate startDate = LocalDate.now();
LocalDate endDate = LocalDate.now().plusDays(1).plusMonths(1).plusYears(1);
// 计算两个日期之间的间隔
Period period = Period.between(startDate, endDate);
System.out.println(period.getYears()); // 1
System.out.println(period.getMonths()); // 1
System.out.println(period.getDays()); // 1
Duration
- 作用:计算两个时间之间的间隔
- 参数类型:LocalTime\LocalDateTime\Instant
LocalDateTime startDateTime = LocalDateTime.now();
LocalDateTime endDateTime = LocalDateTime.now().plusDays(1).plusMonths(1).plusYears(1);
// 计算两个时间之间的间隔
Duration duration = Duration.between(startDateTime, endDateTime);
// 间隔的天数
System.out.println(duration.toDays()); // 366
// 间隔的小时数
System.out.println(duration.toHours()); // 8784
// 间隔的分钟数
System.out.println(duration.toMinutes()); // 527040
// 间隔的秒数(这玩意是个private的,无法访问)
// System.out.println(duration.toSeconds()); // 31622400
// 间隔的毫秒数
System.out.println(duration.toMillis()); // 31622400000
// 间隔的纳秒数
System.out.println(duration.toNanos()); // 31622400000000000