Java8新的时期API
1:LocalDate
1.1:LocalDate基本使用
// 创建一个LocalDate实例
LocalDate date = LocalDate.of(2022, 8, 24);
// LocalDate date = LocalDate.of(2022, Month.AUGUST, 24);
System.out.println(date); // 2022-08-24
// 获取年
int year = date.getYear();
System.out.println(year); // 2022
// 获取月
Month month = date.getMonth();
System.out.println(month); // AUGUST
// 获取日
int day = date.getDayOfMonth();
System.out.println(day); // 24
// 获取星期几
DayOfWeek dow = date.getDayOfWeek();
System.out.println(dow); // WEDNESDAY
// 获取当月天数
int len = date.lengthOfMonth();
System.out.println(len); // 31
// 获取是否是闰年
boolean leap = date.isLeapYear();
System.out.println(leap); // false
1.2:LocalDate获取当前日期
LocalDate today = LocalDate.now();
1.3: 使用TemporalField读取LocalDate的值
还可以通过传递一个TemporalField参数给get方法拿到同样的信息。TemporalField是一个接口,它定义了如何访问temporal对象某个字段的值。ChronoField枚举实现了这一接口,所以你可以很方便地使用get方法得到枚举元素的值。
LocalDate date = LocalDate.now();
int year = date.get(ChronoField.YEAR);
int month = date.get(ChronoField.MONTH_OF_YEAR);
int day = date.get(ChronoField.DAY_OF_MONTH);
1.4:使用解析字符串创建LocalDate
LocalDate date = LocalDate.parse("2022-08-24");
2:LocalTime
2.1:LocalTime基本使用
LocalTime now = LocalTime.now();
// 通过解析代表字符串创建
LocalTime time = LocalTime.parse("13:45:20");
LocalTime time = LocalTime.of(16, 25, 33); ====设置时间:16:25:33
int hour = time.getHour(); ====时:16
int minute = time.getMinute(); ====分:25
int second = time.getSecond(); ====秒:33
int HOUR_OF_DAY = time.get(ChronoField.HOUR_OF_DAY); ====当天过去多少小时:16
int MINUTE_OF_DAY = time.get(ChronoField.MINUTE_OF_DAY); ====当天已过去多少分钟:985
int MINUTE_OF_HOUR = time.get(ChronoField.MINUTE_OF_HOUR); ====距离当前小时过去多少分钟:25
3:合并日期和时间LocalDateTime
3.1创建LocalDateTime对象
LocalDateTime dt1 = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45, 20);
LocalTime time = LocalTime.of(16, 25, 33);
LocalDate date = LocalDate.of(2022, 10, 20);
//通过LocalDateTime.of创建
LocalDateTime dt2 = LocalDateTime.of(date, time);
//向LocalDate传递一个时间对象
LocalDateTime dt3 = date.atTime(13, 45, 20);
LocalDateTime dt4 = date.atTime(time);
//LocalTime传递一个日期对象的方式
LocalDateTime dt5 = time.atDate(date);
3.2:日期拆解
//从LocalDateTime中提取LocalDate或者LocalTime
LocalDate date1 = dt1.toLocalDate();
LocalTime time1 = dt1.toLocalTime();
4:Instant 时间戳
Instant用于表示一个时间戳,它与我们常使用的System.currentTimeMillis()有些类似,不过Instant可以精确到纳秒(Nano-Second),System.currentTimeMillis()方法只精确到毫秒(Milli-Second)。
4.1:时间戳基本使用
Instant now01 = Instant.now();
System.out.println(now01);
System.out.println("纪元秒 : "+now01.getEpochSecond());
System.out.println("时间戳 : "+System.currentTimeMillis());
System.out.println("毫 秒 : "+now01.toEpochMilli());
System.out.println("纳 秒 : "+now01.getNano());
===================================================
2022-10-20T03:12:12.633Z
纪元秒 : 1666235532
时间戳 : 1666235532692
毫 秒 : 1666235532633
纳 秒 : 633000000
===================================================
//获取当前时间戳
Instant instant = Instant.now();
//获得当前时间戳并且增加66毫秒
Instant instant1 = Instant.now().plusMillis(66);
//获得当前时间戳并且减少66毫秒
Instant instant2 = Instant.now().minusMillis(66);
//判断时间戳 instant 是否在 instant1 之后,返回boolean
System.out.println(instant.isAfter(instant1)); //返回false
//判断时间戳 instant 是否在 instant1 之前,返回boolean
System.out.println(instant.isBefore(instant1)); //返回true
//判断两个时间戳是否相等, 返回boolean值
System.out.println(instant.equals(instant1)); //返回false
//获得当前时间戳并增加1小时 通过TimeUnit.HOURS.toMillis(1)将小时转换为毫秒,然后通过plusMillis增加
Instant instant3 = Instant.now().plusMillis(TimeUnit.HOURS.toMillis(1));
//获取时间戳 instant和instant3 相差天数,返回long类型
//如果小于1天,都算零天,大于等于1天,小于2天算一天
System.out.println("相差天数 = " + instant.until(instant3, ChronoUnit.DAYS)); //返回0
//获取时间戳 instant和instant3 相差的小时数,返回long类型
System.out.println("相差小时 = " + instant.until(instant3, ChronoUnit.HOURS)); //返回1
//获取时间戳 instant和instant3 相差的毫秒数,返回long类型
System.out.println("相差毫秒数 = " + instant.until(instant3, ChronoUnit.MILLIS)); //返回3600000
4.2:时间戳转换 LocalDate,LocalDateTime,LocalTime
Instant now = Instant.now();
ZonedDateTime atZone = now.atZone(ZoneOffset.UTC);
//LocalDate
atZone.toLocalDate();
LocalDate date = LocalDate.from(atZone);
//LocalTime
atZone.toLocalTime()
LocalTime.from(atZone)
//LocalDateTime
atZone.toLocalDateTime();
LocalDateTime.from(date);
LocalDateTime.ofInstant(now, ZoneId.systemDefault())
5:使用 Duration 或 Period 计算时间间隔
5.1:Duration 计算两个“时间”间隔的类
LocalDateTime start = LocalDateTime.parse("2022-10-03T10:15:30");
LocalDateTime end = LocalDateTime.parse("2022-10-05T10:25:33");
Duration duration = Duration.between(start, end);
System.out.println("相差的天数="+duration.toDays()); ==2
System.out.println("相差的小时="+ duration.toHours()); ==48
System.out.println("相差的分钟="+duration.toMinutes()); ==2890
System.out.println("相差的秒数="+duration.getSeconds()); ==173403
System.out.println("相差的毫秒="+duration.toMillis()); ==173403000
System.out.println("相差的纳秒="+duration.toNanos()); ==173403000000000
5.2:Period - 计算两个“日期”间隔的类
LocalDate start = LocalDate.of(2020,2,28);
LocalDate end = LocalDate.of(2021,12,3);
Period period = Period.between(start,end);
System.out.println("相差的天数="+ period.getDays());
System.out.println("相差的小时="+period.getMonths());
System.out.println("相差的年="+period.getYears());
6:日期的修改
// 创建一个LocalDate
LocalDate date1 = LocalDate.of(2022, 3, 18); // 2022-03-18
// 直接修改年
LocalDate date2 = date1.withYear(2011); // 2011-03-18
// 直接修改月
LocalDate date3 = date2.withDayOfMonth(25); // 2011-03-25
// 直接修改月
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 9); // 2011-09-25
LocalDate date1 = LocalDate.of(2014, 3, 18); // 2014-03-18
// 周加1
LocalDate date2 = date1.plusWeeks(1); // 2014-03-25
// 年减3
LocalDate date3 = date2.minusYears(3); // 2011-03-25
// 月加6
LocalDate date4 = date3.plus(6, ChronoUnit.MONTHS); // 2011-09-25
7:日期格式化
// 日期转字符串
LocalDate date = LocalDate.now();
String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE); ====20221020
String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE); ====2022-10-20
// 字符串转日期
LocalDate date1 = LocalDate.parse("20220824", DateTimeFormatter.BASIC_ISO_DATE); ====2022-08-24
LocalDate date2 = LocalDate.parse("2022-08-24", DateTimeFormatter.ISO_LOCAL_DATE); ====2022-08-24
// 时间转字符串
LocalTime time = LocalTime.now();
String s1 = time.format(DateTimeFormatter.ISO_TIME); ====14:53:48.278
// 字符串转日期
LocalTime date1 = LocalTime.parse("15:37:42", DateTimeFormatter.ISO_TIME); ====15:37:42
7.1按照自定义模式格式化日期
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate date1 = LocalDate.now();
String formattedDate = date1.format(formatter);
LocalDate date2 = LocalDate.parse(formattedDate, formatter);
8:使用 TemporalAdjuster
有的时候,你需要进行一些更加复杂的操作,比如,将日期调整到下个周日、下个工作日,或者是本月的最后一天。这时,你可以使用重载版本的with方法,向其传递一个提供了更多定制化选择的TemporalAdjuster对象,更加灵活地处理日期。对于最常见的用例,日期和时间API已经提供了大量预定义的TemporalAdjuster。你可以通过TemporalAdjuster类的静态工厂方法访问它们
LocalDate date1 = LocalDate.of(2014, 3, 18);
LocalDate date2 = date1.with(nextOrSame(DayOfWeek.SUNDAY)); ====2014-03-23
LocalDate date3 = date2.with(lastDayOfMonth()); ====2014-03-31
TemporalAdjuster类中的工厂方法
| 方 法 名 | 描 述 |
|---|---|
| dayOfWeekInMonth | 创建一个新的日期,它的值为同一个月中每一周的第几天 |
| firstDayOfMonth | 创建一个新的日期,它的值为当月的第一天 |
| firstDayOfNextMonth | 创建一个新的日期,它的值为下月的第一天 |
| firstDayOfNextYear | 创建一个新的日期,它的值为明年的第一天 |
| firstDayOfYear | 创建一个新的日期,它的值为当年的第一天 |
| firstInMonth | 创建一个新的日期,它的值为同一个月中,第一个符合星期几要求的值 |
| lastDayOfMonth | 创建一个新的日期,它的值为当月的最后一天 |
| lastDayOfYear | 创建一个新的日期,它的值为今年的最后一天 |
| lastInMonth | 创建一个新的日期,它的值为同一个月中,最后一个符合星期几要求的值 |
| next/previous | 创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星期几要求的日期 |
| nextOrSame/previousOrSame | 创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星期几要求的日期,如果该日期已经符合要求,直接返回该对象 |
8.1:实现一个定制的TemporalAdjuster
/*设计一个NextWorkingDay类,该类实现了TemporalAdjuster接口,能够计算明天的日期,同时过滤掉周六和周日这些节假日。**/
public class NextWorkingDay implements TemporalAdjuster {
@Override
public Temporal adjustInto(Temporal temporal) {
DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
int dayToAdd = 1;
if (dow == DayOfWeek.FRIDAY) dayToAdd = 3;
else if (dow == DayOfWeek.SATURDAY) dayToAdd = 2;
return temporal.plus(dayToAdd, ChronoUnit.DAYS);
}
}
//使用自定义方法
date = date.with(new NextWorkingDay());