时间处理是每个项目中都会涉及到的点,但是Date,Calendar等类可读性差,需要对其进行格式化,而且Date对时间处理比较麻烦,想获取年、月、星期的时间太难,并且在转化和时间计算时比较麻烦,另外SimpleDateFormat在处理时间时还存在不安全性;
DK8中在java.time包中新增了操作和日期和时间API,添加了很多常见的api,例如日期/时间比较,加减,格式化等等 方便我们操作时间和日期;
主要提供了以下几个常用api;
1.LocalDate:日期类
2.LocalTime:时间类(相对少用)
3.LocalDateTime:日期和时间类
4.DateTimeFormater: 格式化类
LocalDate是不可变的和线程安全的时间类,且支持时区设置,它是Java 8提供的全新日期时间类。
本文主要记录LocalDate日期类一些常用的api,方便后续查阅;
1. LocalDate获取特定的日期
// 1.1 获取当天
LocalDate toDay = LocalDate.now();
System.out.println("今天日期:" + toDay); //今天日期:2021-12-18
// 1.2 获取特定的日期
LocalDate tempDate = LocalDate.parse("2022-01-01");
LocalDate tempDay = LocalDate.of(2012, 12, 12); //2012-12-12
// 1.3 获取本周周一/周二的日期
LocalDate firstDay = tempDate.with(DayOfWeek.MONDAY);//2021-12-27
LocalDate secondDay = tempDate.with(DayOfWeek.TUESDAY);//2021-12-28
// 1.4 获取本月第一天的日期
LocalDate tempDate2 = LocalDate.parse("2022-01-06");
LocalDate firstDayOfMonth = tempDate2.with(TemporalAdjusters.firstDayOfMonth()); //2022-01-01
// 1.5 本月最后一天日期
LocalDate lastDayOfMonth = tempDate2.with(TemporalAdjusters.lastDayOfMonth()); //2022-01-31
// 1.6 获取本年第一天的日期
LocalDate firsDayOfYear = tempDate2.with(TemporalAdjusters.firstDayOfYear()); //2022-01-01
// 1.7 获取本月的总天数
int TotalDays = tempDate2.withMonth(tempDate2.getMonthValue()).lengthOfMonth(); //31
// 1.8 判断是否是闰年
boolean leapYear = tempDate2.isLeapYear(); //false
2. LocalDate获取日期的年分日
// 2.1 获取日期的年分
System.out.println("当前年分:" + toDay.getYear());//当前年分:2021
// 2.2 获取当前月份
System.out.println("当前月份:" + toDay.getMonth());//当前月份:DECEMBER
System.out.println("当前月份:" + toDay.getMonth().getValue());//当前月份:12
// 2.3 获取当前天数,表示该对象表示的日期是这一年第几天
System.out.println("当前位于一年的多少天:" + toDay.getDayOfYear()); //当前位于一年的多少天:352
// 2.4 获取当前天数,表示该对象表示的日期是这个月第几天
System.out.println("当前当月几号:" + toDay.getDayOfMonth()); //当前当月几号:18
// 2.5 获取日期星期
System.out.println("当前当周周几::" + toDay.getDayOfWeek()); //当前当周周几::SATURDAY
System.out.println("当前当周周几::" + toDay.getDayOfWeek().getValue()); //当前当周周几::6
3. LocalDate修改日期对象
// 3.1 修改日期的年份,返回新对象
LocalDate changYearDate = toDay.withYear(2025); // 2025-12-18
// 3.2 修改日期的月份,返回新对象
LocalDate cahngeMonthDate = toDay.withMonth(11); // 2021-11-18
// 3.3 修改日期在当月的天数,返回新对象
LocalDate changeDayDate = toDay.withDayOfMonth(22); //2021-12-22
// 3.4 修改日期在当年的天数,返回新对象
LocalDate changeDayDate2 = toDay.withDayOfYear(200); //2021-07-19
4. LocalDate获取当前日期之后的日期
4.1 LocalDate日期的加减--获取之后的日期
// 获取当前日期增加指定年份-2年后的日期
LocalDate plusYearDate = toDay.plusYears(2); //2023-12-18
// 获取当前日期增加指定月份-2月后的日期
LocalDate plusMonthDate = toDay.plusMonths(2); // 2022-02-18
// 获取当前日期增加指定星期(2周)后的日期
LocalDate plusWeekDate = toDay.plusWeeks(2); // 2022-01-01
// 获取当前日期增加指定天数-2天后的日期
LocalDate plusDayDate = toDay.plusDays(2);//2021-12-20
4.2 LocalDate日期的加减--获取之前的日期
//获取X年前的时间
LocalDate minusYearsDate = toDay.minusYears(1);
// 获取X月前的时间
LocalDate minusMonthsDate = toDay.minusMonths(1);
// 获取X周前的时间
LocalDate minusWeeksDate = toDay.minusWeeks(1);
// 获取X天前的时间
LocalDate minusDaysDate = toDay.minusDays(1);
5. LocalDate日期之间的比较
LocalDate parseDate = LocalDate.parse("2021-11-11");
LocalDate parseDate2 = LocalDate.parse("2021-11-13");
//compareTo(ChronoLocalDate other) int 比较当前对象和other对象在时间上的大小,返回值如果为正,则当前时间较晚
int i = parseDate.compareTo(parseDate2); // -2
// isBefore(ChronoLocalDate other) boolean 比较当前对象日期是否在other对象之前
boolean before = parseDate.isBefore(parseDate2); // true
// isAfter(ChronoLocalDate other) boolean 比较当前对象日期是否在other对象之后
boolean after = parseDate.isAfter(parseDate2); // false
// isEqual(ChronoLocalDate other) boolean 比较两个日期对象是否相等
boolean equal = parseDate.isEqual(parseDate2); //false
6. LocalDate获取两个日期间隔的天数
LocalDate startDate = LocalDate.parse("2021-09-01");
LocalDate endDate = LocalDate.parse("2021-10-20");
long betweenDays = ChronoUnit.DAYS.between(startDate, endDate); //49
System.out.println(betweenDays);
7. LocalDate获取两个日期间的每一天的日期
List<LocalDate> gapDays = new ArrayList<>();
// 7.1 利用plusDays获取
Stream.iterate(startDate, d -> d.plusDays(1)).limit(ChronoUnit.DAYS.between(startDate, endDate) + 1).forEach(f -> gapDays.add(f));
System.out.println(gapDays); // [2021-09-01, 2021-09-02, 2021-0....2021-10-20]
//7.2 利用minusDays获取
gapDays.clear();
Stream.iterate(endDate, d -> d.minusDays(1)).limit(ChronoUnit.DAYS.between(startDate, endDate) + 1).forEach(f -> gapDays.add(f));
System.out.println(gapDays); //[2021-10-20, 2021-10-19, 2021-10... 2021-09-01]
8. LocalDate和string的相互转化
JDK8之前:SimpleDateFormat来进行格式化,但SimpleDateFormat并不是线程安全的;JDK8之后:引入线程安全的日期与时间DateTimeFormatter来实现格式化
// 8.1 LocalDate转String
LocalDate tempToDay = LocalDate.now();
// 8.1.1 直接利用LocalDate重写后的toString方法
System.out.println(tempToDay.toString()); // 2021-12-20
// 8.1.2 利用DateTimeFormatter类按模板转化
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
System.out.println(tempToDay.format(df)); // 2021-12-20
// 8.2 String转LocalDate
String str = "2021-12-01";
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.parse(str, format);
System.out.println(date); // 2020-01-01
LocalDateTime日期格式的api在后面也会介绍到;