Java 8新特性之新的日期和时间API(3)

操纵更复杂的日期,比如将日期调整到下个周日、下个工作日,或者是本月的最后一天。这时可以使用with的重载版本,向其传递一个提供了更多定制化选择的TemporalAdjuster对象,更加灵活的处理日期。

import static java.time.temporal.TemporalAdjusters.*;

LocalDate dd = LocalDate.of(2018,8,23);

LocalDate dd1 = dd.with(dayOfWeekInMonth(2,DayOfWeek.FRIDAY)); //同一个月中,第二个星期五 2018-08-10

LocalDate dd2 = dd.with(firstDayOfMonth()); //当月的第一天 2018-08-01
        LocalDate dd3 = dd.with(firstDayOfNextMonth()); //下月的第一天 2018-09-01
        LocalDate dd4 = dd.with(firstDayOfNextYear()); //明年的第一天 2019-01-01
        LocalDate dd5 = dd.with(firstDayOfYear()); //当年的第一天 2018-01-01
        LocalDate dd6 = dd.with(firstInMonth(DayOfWeek.MONDAY)); //当月第一个星期一 2018-08-06

LocalDate dd7 = dd.with(lastDayOfMonth()); //当月的最后一天 2018-08-31
        LocalDate dd8 = dd.with(lastDayOfYear()); //当年的最后一天 2018-12-31
        LocalDate dd9 = dd.with(lastInMonth(DayOfWeek.SUNDAY)); //当月最后一个星期日 2018-08-26

LocalDate dd10 = dd.with(previous(DayOfWeek.MONDAY)); //将日期向前调整到第一个符合星期一 2018-08-20
        LocalDate dd11 = dd.with(next(DayOfWeek.MONDAY)); //将日期向后调整到第一个符合星期一 2018-08-27

LocalDate dd12 = dd.with(previousOrSame(DayOfWeek.FRIDAY)); //将日期向前调整第一个符合星期五,如果该日期已经符合,直接返回该对象 2018-08-17
        LocalDate dd13 = dd.with(nextOrSame(DayOfWeek.FRIDAY)); //将日期向后调整第一个符合星期五,如果该日期已经符合,直接返回该对象 2018-08-24

TemporalAdjuster可以进行复杂的日期操作,如果没有找到符合的预定义方法,可以自己创建一个,TemporalAdjuster接口只声明了一个方法所以他说一个函数式接口:

@FunctionalInterface
public interface TemporalAdjuster {
    Temporal adjustInto(Temporal temporal);
}

这意味着TemporalAdjuster接口的实现需要定义如何将一个Temporal对象转换为另一个Temporal对象。比如设计一个NextWorkingDay类,实现计算下一个工作日,过滤掉周六和周日节假日。

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

由于TemporalAdjuster是函数式接口,所以你只能以Lambda表达式的方式向Adjuster接口传递行为:

date.with(t->{

  //上面一坨

})

为了可以重用,TemporalAdjuster对象推荐使用TemporalAdjusters类的静态工厂方法ofDateAdjuster:

LocalDate dd = LocalDate.of(2018, 8, 23);

TemporalAdjuster nextWorkingDay = TemporalAdjusters.ofDateAdjuster(
                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);
                }
        );
        LocalDate next = dd.with(nextWorkingDay);

打印输出及解析日期

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/c7ea4d849be6cbb0ba2bf82b5110a5be.html