Skip to main content
 首页 » 编程设计

介绍 java TemporalAdjuster 类型

2022年07月19日120jackei

介绍 java 8 TemporalAdjuster 类型

本文我们介绍 java 8 TemporalAdjuster 类以及其使用场景。java 8 引入了新的日期、时间库————即java.time包,TemporalAdjuster 类是其中之一。

简而言之,TemporalAdjuster 类是调整Temporal对象的策略。在使用TemporalAdjuster 类之前,我们先看看Temporal接口。

Temporal 接口

Temporal可以根据实际需求表示为日期、时间或两者组合。其几个实现类包括:

LocalDate – 表示没有时区的日期 
LocalDateTime – 表示没有时区的日期和时间 
 

TemporalAdjuster 接口

TemporalAdjuster 是函数接口,在TemporalAdjusters 类中有很多预定义的实现。TemporalAdjuster仅有一个带Temporal对象参数的抽象方法adjustInto()。

TemporalAdjuster可以执行复杂的日期操作,例如,可以获得下一个星期日对于日期、当月的最后一天、下一年的第一天。当然也可以通过旧的java.util.Calendar api实现。不同的是,新api使用预定义的实现抽象出底层逻辑。

TemporalAdjusters类中预定义实现

TemporalAdjusters类有很多预定义的static方法返回TemporalAdjuster对象,使用不同方式调节Temporal对象而与Temporal实现无关。

下面列举部分方法及其定义描述:

  • dayOfWeekInMonth() – 一周中的某一天,例如,三月中第二个星期二
  • firstDayOfMonth() – 当前月的第一天
  • firstDayOfNextMonth() – 下一个月的第一天
  • firstDayOfNextYear() – 下一年的第一天
  • firstDayOfYear() – 当年的第一天
  • lastDayOfMonth() – 当月的最后一天
  • nextOrSame() – 下一次或当天发生的一周中的某天

这些方法的名称都是自解释的,更多TemporalAdjusters参考官方文档

我们从简单实例开始————我们可以使用特定的日期,也可以使用LocalDate.now()获得当前日期。但对本例来说,我们使用固定日期,因为不希望后面期望结果变化造成测试不通过。下面看看如果通过TemporalAdjusters类获得2017-07-08之后的星期日:

@Test 
public void whenAdjust_thenNextSunday() { 
    LocalDate localDate = LocalDate.of(2017, 07, 8); 
    LocalDate nextSunday = localDate.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)); 
      
    String expected = "2017-07-09"; 
      
    assertEquals(expected, nextSunday.toString()); 
} 

再看如何获得当月的最后一天:

LocalDate lastDayOfMonth = localDate.with(TemporalAdjusters.lastDayOfMonth()); 

自定义TemporalAdjuster 实现

我们可以通过两种不同方式自定义TemporalAdjuster 实现。

使用lambda表达式

请看如何通过Temporal.with()方法获得2017-07-09之后14天的日期:

@Test 
public void whenAdjust_thenFourteenDaysAfterDate() { 
    LocalDate localDate = LocalDate.of(2017, 07, 8); 
    TemporalAdjuster temporalAdjuster = t -> t.plus(Period.ofDays(14)); 
    LocalDate result = localDate.with(temporalAdjuster); 
      
    String fourteenDaysAfterDate = "2017-07-22"; 
      
    assertEquals(fourteenDaysAfterDate, result.toString()); 
} 

该示例中,使用了lambda表达式,设置temporalAdjuster为给localDate(2017, 07, 8)对象增加14天。

下面看如何获得2017-07-08之后的工作日,通过自定义TemporalAdjuster 实现,但这次使用static工厂方法ofDateAdjuster():

static TemporalAdjuster NEXT_WORKING_DAY = TemporalAdjusters.ofDateAdjuster(date -> { 
    DayOfWeek dayOfWeek = date.getDayOfWeek(); 
    int daysToAdd; 
    if (dayOfWeek == DayOfWeek.FRIDAY) 
        daysToAdd = 3; 
    else if (dayOfWeek == DayOfWeek.SATURDAY) 
        daysToAdd = 2; 
    else 
        daysToAdd = 1; 
    return today.plusDays(daysToAdd); 
}); 

测试代码:

@Test 
public void whenAdjust_thenNextWorkingDay() { 
    LocalDate localDate = LocalDate.of(2017, 07, 8); 
    TemporalAdjuster temporalAdjuster = NEXT_WORKING_DAY; 
    LocalDate result = localDate.with(temporalAdjuster); 
  
    assertEquals("2017-07-10", date.toString()); 
} 

实现TemporalAdjuster 接口

下面通过实现TemporalAdjuster接口实现同样功能:

public class CustomTemporalAdjuster 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); 
    } 
} 

测试代码:

@Test 
public void whenAdjustAndImplementInterface_thenNextWorkingDay() { 
    LocalDate localDate = LocalDate.of(2017, 07, 8); 
    CustomTemporalAdjuster temporalAdjuster = new CustomTemporalAdjuster(); 
    LocalDate nextWorkingDay = localDate.with(temporalAdjuster); 
      
    assertEquals("2017-07-10", nextWorkingDay.toString()); 
} 

总结

本文我们介绍了TemporalAdjuster接口、TemporalAdjusters类中预定义实现和应用。同时也介绍了两种方法自定义TemporalAdjuster实现。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/88777896
阅读延展