1、jdk8新版日期类api
1.1、日期类
旧版日期时间 API 存在的问题
- 设计很差: 在java.util和java.sql的包中都有日期类,java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期。此外用于格式化和解析的类在java.text包中定义。
- 非线程安全:java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。
- 时区处理麻烦:日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。
LocalDate 、LocalTime、LocalDateTime类的实例是不可变的对象,分别表示使用 ISO -8601 日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息
localDate :日期
LocalTime : 时间
LocalDateTime : 日期+时间
isBefore()、isAfter()、equals()方法来比较两个日期,可直接进行比较。
LocalDate today = LocalDate.now();
System.out.println(today);
//年
System.out.println(today.getYear());
//月
System.out.println(today.getMonth());
//数字月
System.out.println(today.getMonthValue());
//几号
System.out.println(today.getDayOfMonth());
//周几
System.out.println(today.getDayOfWeek());
//一年的第几天
System.out.println(today.getDayOfYear());
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
//修改年份
LocalDateTime localDateTime = now.withYear(54);
System.out.println(localDateTime);
LocalTime localTime = LocalTime.now();
LocalTime localTime1 = localTime.withHour(5);
//修改日期
LocalDate date = LocalDate.of(2020, 4, 1);
System.out.println("date = " + date);
1.1.1、java.time.format.DateTimeFormatter 类可以进行日期时间解析与格式化
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String format = now.format(dtf);
System.out.println(format);
// 将字符串解析为日期时间
LocalDateTime parse = LocalDateTime.parse("1985-09-23 10:12:22", dtf);
System.out.println("parse = " + parse);
1.1.2、JDK 8 的 Instant 类
Instant 时间戳/时间线,内部保存了从1970年1月1日 00:00:00以来的秒和纳秒。
Instant now1 = Instant.now();
System.out.println(now1);
// 获取从1970年1月1日 00:00:00的秒后的纳秒
System.out.println(now1.getNano());
// 获取从1970年1月1日 00:00:00的秒
System.out.println(now1.getEpochSecond());
// 获取从1970年1月1日 00:00:00的毫秒
System.out.println(now1.toEpochMilli());
//获取系统的毫秒
System.out.println(System.currentTimeMillis());
//设置时间
Instant instant = Instant.ofEpochSecond(5);
System.out.println(instant);
1.1.3、计算日期时间差
Duration/Period类: 计算日期时间差。
-
Duration:用于计算2个时间(LocalTime,时分秒)的距离
LocalDateTime now3 = LocalDateTime.now(); LocalDateTime time = now3.withYear(2021); Duration duration = Duration.between(time,now); System.out.println("相差的天数:" + duration.toDays()); System.out.println("相差的小时数:" + duration.toHours()); System.out.println("相差的分钟数:" + duration.toMinutes());
-
Period:用于计算2个日期(LocalDate,年月日)的距离
LocalDate now3 = LocalDate.now();
LocalDate time = now3.withYear(2021);
Period period = Period.between(time,now3);
System.out.println("相差的年:" + period.getYears());
System.out.println("相差的月:" + period.getMonths());
System.out.println("相差的天:" + period.getDays());
1.1.4、TemporalAdjuster
TemporalAdjuster类是一个函数式接口,是Java 8引入的新的处理日期和时间API的一部分。在TemporalAdjusters类中有许多预定义的实现。
该接口有一个名为adjustInto()的抽象方法,可以通过向其传递Temporal对象在其任何实现中调用它。
TemporalAdjuster允许我们执行复杂的日期操作。比如,获得下个星期日,当月的最后一天或下一年的第一天的日期。
1.1.4.1、TemporalAdjusters类中预定义实现
TemporalAdjusters工具类有很多预定义的static方法返回TemporalAdjuster对象,使用不同方式调节Temporal对象而与Temporal实现无关。
LocalDate ld = LocalDate.now();
//当月第一天
System.out.println(ld.with(TemporalAdjusters.firstDayOfMonth()));
//下月第一天
System.out.println(ld.with(TemporalAdjusters.firstDayOfNextMonth()));
//下一年的第一天
System.out.println(ld.with(TemporalAdjusters.firstDayOfNextYear()));
//当年的第一天
System.out.println(ld.with(TemporalAdjusters.firstDayOfYear()));
//当年的最后一天
System.out.println(ld.with(TemporalAdjusters.lastDayOfYear()));
//当月的最后一天
System.out.println(ld.with(TemporalAdjusters.lastDayOfMonth()));
//某月的第一个星期几
System.out.println(ld.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)));
//某月的最后一个星期几
System.out.println(ld.with(TemporalAdjusters.lastInMonth(DayOfWeek.MONDAY)));
//某月的第几个星期几
System.out.println(ld.with(TemporalAdjusters.dayOfWeekInMonth(3,DayOfWeek.MONDAY)));
//不包括当天下一个星期几是几月几号
System.out.println(ld.with(TemporalAdjusters.next(DayOfWeek.MONDAY)));
//获取本周一
System.out.println(ld.with(DayOfWeek.MONDAY));
//获取上周二(minusWeeks(n)n是几就代表几周前)
System.out.println(ld.minusWeeks(1).with(ChronoField.DAY_OF_WEEK,2));
//下周二
System.out.println(ld.plusWeeks(1).with(ChronoField.DAY_OF_WEEK,2));
//往后包括今天最近星期几的日期
System.out.println(ld.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY)));
//往前不包括今天上一个星期几是几月几号
System.out.println(ld.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY)));
//往前包括今天最近星期几的日期
System.out.println(ld.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)));
1.1.4.2、自定义TemporalAdjuster实现
1.用lambda表达式
1.1往后7天
LocalDate localDate = LocalDate.of(2022, 12, 2);
TemporalAdjuster temporalAdjuster = t -> t.plus(Period.ofDays(7));
LocalDate result = localDate.with(temporalAdjuster);
System.out.println(result);
1.2计算下一个工作日
LocalDate nextWorkDay = LocalDate.now().with(tempDate ->{
LocalDate localDate1 = (LocalDate) tempDate;
DayOfWeek dayOfWeek = localDate1.getDayOfWeek();
if (dayOfWeek.equals(DayOfWeek.FRIDAY)){
return localDate1.plusDays(3);
}
else if (dayOfWeek.equals(DayOfWeek.SATURDAY)){
return localDate1.plusDays(2);
}
else {
return localDate1.plusDays(1);
}
});
2.实现TemporalAdjuster接口
计算下一个工作日
public static class CustomTemporalAdjustter implements TemporalAdjuster{
@Override
public Temporal adjustInto(Temporal temporal) {
DayOfWeek dayOfWeek = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
int daysToAdd;
if (dayOfWeek == DayOfWeek.FRIDAY){
daysToAdd = 3;
}
else if (dayOfWeek == DayOfWeek.SATURDAY){
daysToAdd = 2;
}
else {
daysToAdd = 1;
}
return temporal.plus(daysToAdd, ChronoUnit.DAYS);
}
}
//测试代码
CustomTemporalAdjustter customTemporalAdjustter = new CustomTemporalAdjustter();
LocalDate with = localDate.with(customTemporalAdjustter);
System.out.println(with);