不同的日期API展示了日期处理的演进

44 阅读2分钟
  • wrong1()方法直接用Date加整数表示30天,这是错误的做法,因为Date是毫秒级,整数相加会导致溢出。

  • wrong1fix()方法改为用long型表示30天的毫秒数,避免了整数加法溢出。

  • right()方法使用Calendar进行日期运算,这是较早的标准做法。

  • better()方法使用Java 8中的LocalDateTime,这是目前推荐的现代日期API。

  • test()方法展示了LocalDate各种便利的日期操作示例,包括加减、计算天数差、调整到本月第一天、获取特定日期等。

  • TemporalAdjuster进行日期调整、自定义日期查询逻辑等高级用法。

public class CommonMistakesApplication {

    public static void main(String[] args) throws Exception {
        wrong1();
        wrong1fix();
        right();
        better();
        test();
    }

    private static void wrong1() {
        System.out.println("wrong1");
        Date today = new Date();
        Date nextMonth = new Date(today.getTime() + 30 * 1000 * 60 * 60 * 24);
        System.out.println(today);
        System.out.println(nextMonth);
    }

    private static void wrong1fix() {
        System.out.println(30 * 1000 * 60 * 60 * 24 + " " + (30L * 1000 * 60 * 60 * 24 > Integer.MAX_VALUE));
        System.out.println("wrong1fix");
        Date today = new Date();
        Date nextMonth = new Date(today.getTime() + 30L * 1000 * 60 * 60 * 24);
        System.out.println(today);
        System.out.println(nextMonth);

    }

    private static void right() {
        System.out.println("right");
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DAY_OF_MONTH, 30);
        System.out.println(c.getTime());
    }

    private static void better() {
        System.out.println("better");
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime.plusDays(30));
    }

    private static void test() {
        System.out.println("//测试操作日期");
        System.out.println(LocalDate.now()
                .minus(Period.ofDays(1))
                .plus(1, ChronoUnit.DAYS)
                .minusMonths(1)
                .plus(Period.ofMonths(1)));

        System.out.println("//计算日期差");
        LocalDate today = LocalDate.of(2019, 12, 12);
        LocalDate specifyDate = LocalDate.of(2019, 10, 1);
        System.out.println(Period.between(specifyDate, today).getDays());
        System.out.println(Period.between(specifyDate, today));
        System.out.println(ChronoUnit.DAYS.between(specifyDate, today));


        System.out.println("//本月的第一天");
        System.out.println(LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()));

        System.out.println("//今年的程序员日");
        System.out.println(LocalDate.now().with(TemporalAdjusters.firstDayOfYear()).plusDays(255));

        System.out.println("//今天之前的一个周六");
        System.out.println(LocalDate.now().with(TemporalAdjusters.previous(DayOfWeek.SATURDAY)));

        System.out.println("//本月最后一个工作日");
        System.out.println(LocalDate.now().with(TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY)));

        System.out.println("//自定义逻辑");
        System.out.println(LocalDate.now().with(temporal -> temporal.plus(ThreadLocalRandom.current().nextInt(100), ChronoUnit.DAYS)));

        System.out.println("//查询是否是今天要举办生日");
        System.out.println(LocalDate.now().query(CommonMistakesApplication::isFamilyBirthday));

    }

    public static Boolean isFamilyBirthday(TemporalAccessor date) {
        int month = date.get(MONTH_OF_YEAR);
        int day = date.get(DAY_OF_MONTH);

        if (month == Month.FEBRUARY.getValue() && day == 17)
            return Boolean.TRUE;
        if (month == Month.SEPTEMBER.getValue() && day == 21)
            return Boolean.TRUE;
        if (month == Month.MAY.getValue() && day == 22)
            return Boolean.TRUE;
        return Boolean.FALSE;
    }
}

学习:Java 业务开发常见错误 100 例学习笔记