**Java8新的时期API**

126 阅读6分钟

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());