12.2 操纵、解析和格式化日期

直接修改

LocalDate date1 = LocalDate.of(2014, 3, 18); // 2014-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
LocalDate date2 = date1.minusYears(3); // 2011-03-18
LocalDate date3 = date2.plusWeeks(1); // 2011-03-25
LocalDate date4 = date3.plus(6, ChronoUnit.MONTHS); // 2011-09-25

测验12.1操纵LocalDate对象
经过下面这些操作,date变量的值是什么?

LocalDate date = LocalDate.of(2014, 3, 18); // 2014-03-18
date = date.with(ChronoField.MONTH_OF_YEAR, 9); // 2014-09-18
date = date.plusYears(2).minusDays(10); // 2016-09-08
date.withYear(2011); // 2011-09-08
System.out.println(date); // 2016-09-08

注意:最后一次date.withYear(2011);修改后未赋值,因此结果是2016-09-08。

12.2.1 使用TemporalAdjuster

更复杂的日期操作,例如,将日期调整到下个周日、下个工作日,或者是本月的最后一天。

基于java.time.temporal.Temporal#with(TemporalAdjuster adjuster)实现日期的调整。

java.time.temporal.TemporalAdjusters的静态方法中提供了大量预定义的TemporalAdjuster。

TemporalAdjuster将一个Temporal对象转换为一个Temporal对象并返回

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

测验12.2 实现一个定制的TemporalAdjuster

请设计一个NextWorkingDay类,该类实现了TemporalAdjuster接口,能够计算下一个工作日(不考虑法定年节假日)。

如果当天的星期介于周一至周五之间,日期向后移动一天;如果当天是周六或者周日,则返回下一个周一。

class NextWorkingDay implements TemporalAdjuster {
    @Override
    public Temporal adjustInto(Temporal temporal) {
        if (Objects.isNull(temporal)) {
            return null;
        }
        DayOfWeek dayOfWeek = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
        int dayToAdd = 1;
        if (dayOfWeek == DayOfWeek.FRIDAY) {
            dayToAdd = 3;
        } else if (dayOfWeek == DayOfWeek.SATURDAY) {
            dayToAdd = 2;
        }
        return temporal.plus(dayToAdd, ChronoUnit.DAYS);
    }
}

使用

  1. 基于对象:date.with(new NextWorkingDay())

  2. 基于lambda表达式;

    date.with(temporal -> {
        if (Objects.isNull(temporal)) {
            return null;
        }
        DayOfWeek dayOfWeek = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
        int dayToAdd = 1;
        if (dayOfWeek == DayOfWeek.FRIDAY) {
            dayToAdd = 3;
        } else if (dayOfWeek == DayOfWeek.SATURDAY) {
            dayToAdd = 2;
        }
        return temporal.plus(dayToAdd, ChronoUnit.DAYS);
    });
    
  3. 基于静态工厂方法TemporalAdjuster#ofDateAdjuster生成TemporalAdjuster;

    TemporalAdjuster temporalAdjuster = TemporalAdjusters.ofDateAdjuster(temporal -> {
        if (Objects.isNull(temporal)) {
            return null;
        }
        DayOfWeek dayOfWeek = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
        int dayToAdd = 1;
        if (dayOfWeek == DayOfWeek.FRIDAY) {
            dayToAdd = 3;
        } else if (dayOfWeek == DayOfWeek.SATURDAY) {
            dayToAdd = 2;
        }
        return temporal.plus(dayToAdd, ChronoUnit.DAYS);
    });
    
    date.with(temporalAdjuster);
    

12.2.2 打印输出及解析日期-时间对象

java.util.time提供了格式化以及解析日期-时间对象的能力。

// DateTimeFormatter预定义格式化
LocalDate date = LocalDate.of(2014, 3, 18);
String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE); // 20140318
String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE); // 2014-03-18

// DateTimeFormatter预定义解析
LocalDate date1 = LocalDate.parse(s1, DateTimeFormatter.BASIC_ISO_DATE); // LocalDate.of(2014, 3, 18)
LocalDate date2 = LocalDate.parse(s2, DateTimeFormatter.ISO_LOCAL_DATE); // LocalDate.of(2014, 3, 18)

// DateTimeFormatter自定义格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String formattedDate = date.format(formatter); // 18/03/2014
// DateTimeFormatter自定义解析
LocalDate date3 = LocalDate.parse(formattedDate, formatter); // LocalDate.of(2014, 3, 18)

// DateTimeFormatter自定义本地化格式化
DateTimeFormatter italianFormatter = DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.ITALIAN);
String italianFormat = date.format(italianFormatter); // 18. marzo 2014
// DateTimeFormatter自定义本地化解析
LocalDate date4 = LocalDate.parse(italianFormat, italianFormatter);
// DateTimeFormatter自定义更复杂格式的解析器
public static DateTimeFormatter buildItalianFormatter() {
    DateTimeFormatter italianFormatter = new DateTimeFormatterBuilder()
            .appendText(ChronoField.DAY_OF_MONTH)
            .appendLiteral(". ")
            .appendText(ChronoField.MONTH_OF_YEAR)
            .appendLiteral(" ")
            .appendText(ChronoField.YEAR)
            .parseCaseInsensitive()
            .toFormatter(Locale.ITALIAN);
    return italianFormatter;
}
posted @ 2023-06-03 22:25  蒋智  阅读(12)  评论(0)    收藏  举报