Java 日期/时间

LocalDate(日期,不含时间)

LocalDate 是 Java 8 引入的日期时间 API(位于 java.time 包)中的一个类,专门用于表示不含时间信息的日期(年、月、日),例如 2023-10-05。它是不可变的、线程安全的,相比传统的 Date 类更加直观和易用。

LocalDate 是 Java 8 引入的 java.time 日期时间 API 中的核心类之一,专门用于表示不含时间信息的日期,仅包含年、月、日三个字段(格式如 2023-10-05)。它解决了传统 java.util.Date 和 java.util.Calendar 类的设计缺陷,具有不可变性、线程安全性和直观的 API 设计,是处理纯日期场景的最佳选择。

核心特性

  • 不可变性:一旦创建,LocalDate 对象的值无法修改,所有修改操作(如增减天数)都会返回一个新的实例,避免线程安全问题。

  • 纯日期信息:仅包含年、月、日,不涉及时区、时间(时 / 分 / 秒)或毫秒,适合生日、节假日等纯日期场景。

  • 丰富的日期操作:提供了简洁的方法用于日期计算、字段提取和比较,无需手动处理月份天数差异、闰年等复杂逻辑。

主要用途

  • 记录生日、纪念日等仅需日期的信息

  • 处理日历相关业务(如计算两个日期之间的天数)

  • 数据库日期字段的映射(与 DATE 类型对应)

  • 生成报表或日志中的日期标记

与传统日期类的对比

特性

LocalDate

传统 Date/Calendar

时间信息

仅包含日期(年 / 月 / 日)

包含日期 + 时间,甚至时区

可变性

不可变(线程安全)

可变(线程不安全)

API 设计

方法直观(如 plusDays())

方法繁琐(如 add(Calendar.DATE, 1))

时区依赖

与时区无关

隐含默认时区,易导致混淆

简单示例

下面示例将演示 LocalDate 类的基本用法:

import java.time.LocalDate;

public class LocalDateDemo {
    public static void main(String[] args) {
        // 获取当前日期
        LocalDate today = LocalDate.now();
        System.out.println("今天: " + today); // 输出: 2023-10-05(示例)

        // 计算10天后的日期
        LocalDate future = today.plusDays(10);
        System.out.println("10天后: " + future);

        // 判断是否为闰年
        boolean isLeap = today.isLeapYear();
        System.out.println("今年是闰年? " + isLeap);
    }
}

运行结果:

今天: 2025-09-01
10天后: 2025-09-11
今年是闰年? false

常用方法及示例

创建 LocalDate 对象

now() - 获取当前日期

now() 是 LocalDate 类的静态方法,用于获取当前系统默认时区下的本地日期(仅包含年、月、日,不包含时间信息)。

基于系统时钟和默认时区,返回代表“今天”的 LocalDate 实例。例如,若系统当前日期是 2024 年 9 月 1 日,则返回 2024-09-01。

默认使用系统的时区(可通过 ZoneId.systemDefault() 获取),若需指定时区,可使用重载方法 LocalDate.now(ZoneId zone)。

该方法返回的 LocalDate 对象是不可变的,后续无法修改其日期值,确保线程安全。

示例:

import java.time.LocalDate;
import java.time.ZoneId;

public class LocalDateNowExample {
    public static void main(String[] args) {
        // 1. 获取系统默认时区的当前日期
        LocalDate today = LocalDate.now();
        System.out.println("系统默认时区的当前日期:" + today); // 例如:2024-09-01

        // 2. 指定时区获取当前日期(如纽约时区)
        ZoneId newYorkZone = ZoneId.of("America/New_York");
        LocalDate todayInNY = LocalDate.now(newYorkZone);
        System.out.println("纽约时区的当前日期:" + todayInNY); // 可能与默认时区不同

        // 3. 验证无时间信息(仅日期)
        System.out.println("年份:" + today.getYear());       // 2024
        System.out.println("月份:" + today.getMonthValue()); // 9
        System.out.println("日:" + today.getDayOfMonth());   // 1
    }
}

运行结果:

系统默认时区的当前日期:2025-09-01
纽约时区的当前日期:2025-09-01
年份:2025
月份:9
日:1

注意事项:

  • 若程序需要在不同时区下统一日期计算,建议显式指定时区(如 ZoneId.of("UTC")),避免依赖系统默认时区导致不一致。

  • 该方法的实现依赖 Clock.systemDefaultZone()(默认时钟),若需模拟特定日期进行测试,可使用 LocalDate.now(Clock clock) 传入自定义时钟。

of(int year, int month, int dayOfMonth) - 创建指定日期

of() 方法是 LocalDate 类的一个静态工厂方法,用于根据指定的年、月、日创建一个 LocalDate 实例。它是创建 LocalDate 对象最常用的方式之一,返回的 LocalDate 不包含时间信息,仅表示一个具体的日历日期。

参数说明:

  • year:年份(支持正负值,例如公元元年为 1,公元前 1 年为 0,公元前 2 年为 -1 等)。

  • month:月份(1-12 的整数,1 代表 1 月,12 代表 12 月)。

  • dayOfMonth:当月的天数(需符合实际月份的天数,例如 1 月最多 31 天,2 月平年 28 天、闰年 29 天等)。

注意:该方法会自动校验参数是否符合日历规则,若无效则抛出 DateTimeException。如果月份传入 0 或 13、2 月传入 30 天等情况都会触发异常。

示例:

import java.time.LocalDate;
import java.time.DateTimeException;

public class LocalDateOfExample {
    public static void main(String[] args) {
        // 正常创建:2024年3月15日
        LocalDate date1 = LocalDate.of(2024, 3, 15);
        System.out.println("创建的日期:" + date1); // 输出:2024-03-15

        // 验证闰年2月29日(2024是闰年)
        LocalDate leapDay = LocalDate.of(2024, 2, 29);
        System.out.println("闰年2月29日:" + leapDay); // 输出:2024-02-29

        // 无效参数示例(会抛出异常)
        try {
            // 2023年不是闰年,2月没有29天
            LocalDate invalidDate = LocalDate.of(2023, 2, 29);
        } catch (DateTimeException e) {
            System.out.println("异常信息:" + e.getMessage()); 
            // 输出:Invalid date 'February 29' as '2023' is not a leap year
        }
    }
}

运行结果:

创建的日期:2024-03-15
闰年2月29日:2024-02-29
异常信息:Invalid date 'February 29' as '2023' is not a leap year

注意事项:

  • 月份参数是1-based(1 代表 1 月),与 java.util.Calendar 类的 0-based 月份(0 代表 1 月)不同,使用时需注意区分。

  • 若需要通过 Month 枚举类指定月份(如 Month.MARCH 代表 3 月),可使用重载方法 LocalDate.of(int year, Month month, int dayOfMonth),例如:LocalDate.of(2024, Month.MARCH, 15)(效果与 of(2024, 3, 15) 一致)。

  

日期操作方法

plusDays(long daysToAdd) - 增加天数

用于在当前日期基础上增加指定天数,返回一个新的 LocalDate 实例。由于 LocalDate 是不可变类,原实例不会被修改。

方法参数与返回值:

  • 参数:daysToAdd(long 类型),表示要增加的天数(支持负数,即减去指定天数)。

  • 返回值:一个新的 LocalDate 实例,代表增加天数后的日期。

注意:

(1) 该方法无需手动计算月份 / 年份的边界(如月底加一天自动进入下月,年底加一天自动进入下年)。例如:2024-02-28 加 1 天 → 2024-02-29(2024 是闰年);2023-12-31 加 1 天 → 2024-01-01。

(2) 支持负数参数,当 daysToAdd 为负数时,等效于减去指定天数(与 minusDays(long daysToSubtract) 效果一致)。例如:plusDays(-3) 等同于减去 3 天。

示例:

import java.time.LocalDate;

public class LocalDatePlusDaysExample {
    public static void main(String[] args) {
        // 基础日期:2024-03-15
        LocalDate baseDate = LocalDate.of(2024, 3, 15);
        System.out.println("基础日期:" + baseDate);

        // 1. 增加正数天数(跨月)
        LocalDate plus10Days = baseDate.plusDays(10);
        System.out.println("加10天:" + plus10Days); // 2024-03-25

        // 2. 增加天数跨月(3月有31天)
        LocalDate crossMonth = baseDate.plusDays(20);
        System.out.println("加20天(跨月):" + crossMonth); // 2024-04-04

        // 3. 增加天数跨年
        LocalDate crossYear = LocalDate.of(2024, 12, 30).plusDays(5);
        System.out.println("加5天(跨年):" + crossYear); // 2025-01-04

        // 4. 传入负数(等效于减天数)
        LocalDate minus5Days = baseDate.plusDays(-5);
        System.out.println("加-5天(即减5天):" + minus5Days); // 2024-03-10
    }
}

运行结果:

基础日期:2024-03-15
加10天:2024-03-25
加20天(跨月):2024-04-04
加5天(跨年):2025-01-04
加-5天(即减5天):2024-03-10

注意,若需要增加月份或年份,可使用同类方法 plusMonths(long monthsToAdd) 或 plusYears(long yearsToAdd),它们同样会自动处理日历规则。

minusMonths(long monthsToSubtract) - 减少月份

用于在当前日期基础上减去指定的月份数,返回一个新的 LocalDate 实例。由于 LocalDate 是不可变类,原实例不会被修改。

方法参数与返回值:

  • 参数:monthsToSubtract(long 类型),表示要减去的月份数(支持负数,即等效于增加指定月份)。

  • 返回值:一个新的 LocalDate 实例,代表减去月份后的日期。

注意:

(1)当减去月份后导致日期超出目标月份的最大天数时,会自动调整为目标月份的最后一天。例如:2024-03-31 减去 1 个月 → 2024-02-29(2024 是闰年,2 月最多 29 天);2023-03-31 减去 1 个月 → 2023-02-28。

(2)当 monthsToSubtract 为负数时,等效于增加指定月份(与 plusMonths(long monthsToAdd) 效果一致)。例如:minusMonths(-3) 等同于增加 3 个月。

示例:

import java.time.LocalDate;

public class LocalDateMinusMonthsExample {
    public static void main(String[] args) {
        // 基础日期:2024-05-15
        LocalDate baseDate = LocalDate.of(2024, 5, 15);
        System.out.println("基础日期:" + baseDate);

        // 1. 减去1个月
        LocalDate minus1Month = baseDate.minusMonths(1);
        System.out.println("减1个月:" + minus1Month); // 2024-04-15

        // 2. 减去3个月(跨年)
        LocalDate crossYear = LocalDate.of(2024, 2, 10).minusMonths(3);
        System.out.println("减3个月(跨年):" + crossYear); // 2023-11-10

        // 3. 处理月份天数溢出(自动调整为当月最后一天)
        LocalDate overflowDate1 = LocalDate.of(2024, 3, 31).minusMonths(1);
        System.out.println("3月31日减1个月:" + overflowDate1); // 2024-02-29(闰年)

        LocalDate overflowDate2 = LocalDate.of(2023, 3, 31).minusMonths(1);
        System.out.println("2023年3月31日减1个月:" + overflowDate2); // 2023-02-28(平年)

        // 4. 传入负数(等效于加月份)
        LocalDate plus2Months = baseDate.minusMonths(-2);
        System.out.println("减-2个月(即加2个月):" + plus2Months); // 2024-07-15
    }
}

运行结果:

基础日期:2024-05-15
减1个月:2024-04-15
减3个月(跨年):2023-11-10
3月31日减1个月:2024-02-29
2023年3月31日减1个月:2023-02-28
减-2个月(即加2个月):2024-07-15

注意事项:

  • 月份增减的逻辑是 “优先保持日期,超出则取月末”,这与人类日常习惯一致(例如 “2024-01-30 减 1 个月” 会得到 “2023-12-30”,而 “2024-03-30 减 1 个月” 会得到 “2024-02-29”)。

  • 若需要减去天数或年份,可使用同类方法 minusDays(long daysToSubtract) 或 minusYears(long yearsToSubtract)。

withYear(int year) - 修改年份

用于修改当前日期的年份,返回一个新的 LocalDate 实例。由于 LocalDate 是不可变类,原实例的年份不会被修改。

方法参数与返回值:

  • 参数:year(int 类型),表示要设置的新年份(支持正负值,如公元前年份)。

  • 返回值:一个新的 LocalDate 实例,其年份为指定值,月和日与原实例保持一致(若新年份导致日期无效,会自动调整)。

注意:

(1)当修改年份后,原日期的 “月 - 日” 组合在新年份中无效时(如 2023-02-29 改为 2024 年时),会自动调整为有效日期(2024-02-29 是合法的闰年日期,无需调整;而 2024-02-29 改为 2025 年时,会调整为 2025-02-28)。

(2)仅修改年份,原日期的月份和天数会尽可能保留(除非因闰年 / 平年导致无效)。

示例:

import java.time.LocalDate;

public class LocalDateWithYearExample {
    public static void main(String[] args) {
        // 基础日期:2023-03-15
        LocalDate baseDate = LocalDate.of(2023, 3, 15);
        System.out.println("基础日期:" + baseDate);

        // 1. 修改为指定年份(2024)
        LocalDate newYearDate = baseDate.withYear(2024);
        System.out.println("修改为2024年:" + newYearDate); // 2024-03-15

        // 2. 处理闰年2月29日的特殊情况
        LocalDate leapDay = LocalDate.of(2024, 2, 29); // 2024是闰年
        System.out.println("原闰年日期:" + leapDay);

        // 改为平年(2025),2月29日无效,自动调整为2月28日
        LocalDate adjustedDate = leapDay.withYear(2025);
        System.out.println("改为2025年(平年):" + adjustedDate); // 2025-02-28

        // 3. 改为公元前年份
        LocalDate bcDate = baseDate.withYear(-5); // 公元前5年
        System.out.println("改为公元前5年:" + bcDate); // -0005-03-15

        // 4. 保持月日不变(即使跨多年)
        LocalDate decadeLater = baseDate.withYear(2033);
        System.out.println("改为2033年:" + decadeLater); // 2033-03-15
    }
}

运行结果:

基础日期:2023-03-15
修改为2024年:2024-03-15
原闰年日期:2024-02-29
改为2025年(平年):2025-02-28
改为公元前5年:-0005-03-15
改为2033年:2033-03-15

注意事项:

  • 若需修改月份,可使用 withMonth(int month);修改天数,可使用 withDayOfMonth(int dayOfMonth);修改为当月第几天,还可使用 withDayOfYear(int dayOfYear)(如 withDayOfYear(1) 表示当年 1 月 1 日)。

  • 日期调整逻辑遵循 “尽可能保留原月日,无效则调整为当月最后一天” 的规则,与人类对日期的直觉理解一致。

  

获取日期字段

getYear() - 获取年份

用于获取当前日期对象中的年份值(以整数形式返回)。支持正负年份:

  • 公元后年份为正数(如 2024、1990)。

  • 公元前年份为负数(如公元前 5 年返回 -5,公元前 1 年返回 0)。

示例:

import java.time.LocalDate;

public class LocalDateGetYearExample {
    public static void main(String[] args) {
        // 1. 获取当前日期的年份
        LocalDate today = LocalDate.now();
        int currentYear = today.getYear();
        System.out.println("当前年份:" + currentYear); // 例如:2024

        // 2. 获取指定日期的年份
        LocalDate specificDate = LocalDate.of(1995, 12, 3);
        int year = specificDate.getYear();
        System.out.println("指定日期的年份:" + year); // 输出:1995

        // 3. 处理公元前年份
        LocalDate bcDate = LocalDate.of(-4712, 1, 1); // 天文历法中的起始日期
        int bcYear = bcDate.getYear();
        System.out.println("公元前年份:" + bcYear); // 输出:-4712

        // 4. 结合日期修改方法使用
        LocalDate modifiedDate = specificDate.withYear(2028);
        System.out.println("修改后的年份:" + modifiedDate.getYear()); // 输出:2028
    }
}

运行结果:

当前年份:2025
指定日期的年份:1995
公元前年份:-4712
修改后的年份:2028

注意事项:

  • 与 java.util.Date 类不同,LocalDate 直接提供 getYear() 方法获取直观的年份(如 2024 直接返回 2024),无需额外计算(Date 类需通过 Calendar 转换才能得到正确年份)。

  • 若需获取月份或天数,可使用同类方法 getMonthValue()(返回 1-12 的月份值)或 getDayOfMonth()(返回当月天数)。

getMonthValue() - 获取月份数值(1-12)

用于获取当前日期中月份的数值(1-12),其中 1 代表 1 月,12 代表 12 月。与日常生活中对月份的称呼一致(1 月即返回 1),无需像 java.util.Calendar 那样进行 +1 调整(Calendar 中 0 代表 1 月)。

示例:

import java.time.LocalDate;

public class LocalDateGetMonthValueExample {
    public static void main(String[] args) {
        // 1. 获取当前日期的月份
        LocalDate today = LocalDate.now();
        int currentMonth = today.getMonthValue();
        System.out.println("当前月份(数值):" + currentMonth); // 例如:9(代表9月)

        // 2. 获取指定日期的月份
        LocalDate christmas = LocalDate.of(2024, 12, 25);
        int christmasMonth = christmas.getMonthValue();
        System.out.println("圣诞节所在月份:" + christmasMonth); // 输出:12(12月)

        // 3. 结合月份修改方法使用
        LocalDate modifiedDate = christmas.withMonth(6); // 修改为6月
        System.out.println("修改后的月份:" + modifiedDate.getMonthValue()); // 输出:6(6月)

        // 4. 遍历一年中的所有月份
        System.out.println("\n一年中的所有月份数值:");
        LocalDate base = LocalDate.of(2024, 1, 1);
        for (int i = 0; i < 12; i++) {
            System.out.println(base.plusMonths(i).getMonthValue() + "月");
        }
    }
}

运行结果:

当前月份(数值):9
圣诞节所在月份:12
修改后的月份:6

一年中的所有月份数值:
1月
2月
3月
4月
5月
6月
7月
8月
9月
10月
11月
12月

注意事项:若需要获取月份的枚举对象(如 Month.JANUARY)而非数值,可使用 getMonth() 方法,例如:Month month = LocalDate.now().getMonth();(返回 Month.SEPTEMBER 代表 9 月)。

getDayOfWeek() - 获取星期几

用于获取当前日期对应的星期几(星期几),返回 DayOfWeek 枚举类型。DayOfWeek 枚举对象,包含 7 个枚举常量,分别对应周一到周日:

MONDAY(周一)、TUESDAY(周二)、WEDNESDAY(周三)、THURSDAY(周四)、FRIDAY(周五)、SATURDAY(周六)、SUNDAY(周日)。

注意,DayOfWeek 枚举类还提供了额外方法,如 getValue() 可获取 1-7 的数值(1 代表周一,7 代表周日),方便进行数值化处理。

示例:

import java.time.DayOfWeek;
import java.time.LocalDate;

public class LocalDateGetDayOfWeekExample {
    public static void main(String[] args) {
        // 1. 获取当前日期的星期几
        LocalDate today = LocalDate.now();
        DayOfWeek todayOfWeek = today.getDayOfWeek();
        System.out.println("当前星期:" + todayOfWeek); // 例如:MONDAY(周一)

        // 2. 获取星期对应的数值(1=周一,7=周日)
        int dayValue = todayOfWeek.getValue();
        System.out.println("星期对应数值:" + dayValue); // 例如:1

        // 3. 检查指定日期是周末还是工作日
        LocalDate weekend = LocalDate.of(2024, 9, 7); // 2024-09-07 是周六
        DayOfWeek weekendDay = weekend.getDayOfWeek();
        
        if (weekendDay == DayOfWeek.SATURDAY || weekendDay == DayOfWeek.SUNDAY) {
            System.out.println(weekend + " 是周末"); // 输出:2024-09-07 是周末
        }

        // 4. 遍历一周的所有星期
        System.out.println("\n一周的所有星期:");
        for (DayOfWeek day : DayOfWeek.values()) {
            System.out.println(day + "(数值:" + day.getValue() + ")");
        }
    }
}

运行结果:

当前星期:MONDAY
星期对应数值:1
2024-09-07 是周末

一周的所有星期:
MONDAY(数值:1)
TUESDAY(数值:2)
WEDNESDAY(数值:3)
THURSDAY(数值:4)
FRIDAY(数值:5)
SATURDAY(数值:6)
SUNDAY(数值:7)

注意事项:

  • 与传统 java.util.Calendar 不同(Calendar 中 1 代表周日),DayOfWeek 遵循国际标准,1 代表周一,7 代表周日,更符合全球多数地区的习惯。

  • 若需直接获取星期的中文描述,可结合 java.time.format.TextStyle 实现本地化显示,例如:
    String chineseDay = todayOfWeek.getDisplayName(TextStyle.FULL, Locale.CHINESE);(返回 “星期一”)。

日期比较

isAfter(LocalDate other) - 判断是否在指定日期之后

用于判断当前日期是否在另一个日期之后,返回 boolean 类型结果(true 表示当前日期在参数日期之后,false 则表示不满足)。

方法参数与返回值:

  • 参数:other(LocalDate 类型),表示要比较的另一个日期。

  • 返回值:boolean 值,true 当且仅当当前日期严格晚于 other 日期,否则为 false(包括等于的情况)。

注意:

(1) 仅当当前日期在参数日期的 “之后”(即更晚)时返回 true,若两个日期相等则返回 false。

(2)仅比较年、月、日,不涉及时间信息(与 LocalDateTime.isAfter() 不同)。

(3)参数为 null 时会抛出 NullPointerException,需提前处理 null 情况。

示例:

import java.time.LocalDate;

public class LocalDateIsAfterExample {
    public static void main(String[] args) {
        // 基础日期:2024-09-01
        LocalDate baseDate = LocalDate.of(2024, 9, 1);
        
        // 1. 比较当前日期是否在之后(参数日期更早)
        LocalDate earlierDate = LocalDate.of(2024, 8, 31);
        boolean isAfter1 = baseDate.isAfter(earlierDate);
        System.out.println(baseDate + " 是否在 " + earlierDate + " 之后?" + isAfter1); // true
        
        // 2. 比较当前日期是否在之后(参数日期更晚)
        LocalDate laterDate = LocalDate.of(2024, 9, 2);
        boolean isAfter2 = baseDate.isAfter(laterDate);
        System.out.println(baseDate + " 是否在 " + laterDate + " 之后?" + isAfter2); // false
        
        // 3. 比较相等的日期
        LocalDate sameDate = LocalDate.of(2024, 9, 1);
        boolean isAfter3 = baseDate.isAfter(sameDate);
        System.out.println(baseDate + " 是否在 " + sameDate + " 之后?" + isAfter3); // false
        
        // 4. 跨年份比较
        LocalDate lastYear = LocalDate.of(2023, 12, 31);
        boolean isAfter4 = baseDate.isAfter(lastYear);
        System.out.println(baseDate + " 是否在 " + lastYear + " 之后?" + isAfter4); // true
    }
}

运行结果:

2024-09-01 是否在 2024-08-31 之后?true
2024-09-01 是否在 2024-09-02 之后?false
2024-09-01 是否在 2024-09-01 之后?false
2024-09-01 是否在 2023-12-31 之后?true

注意事项:

  • isBefore(LocalDate other) 用于判断当前日期是否在参数日期之前。

  • 若需判断两个日期是否相等,应使用 isEqual(LocalDate other) 方法(baseDate.isEqual(otherDate))。

  • 常用于日期区间校验(如判断某个日期是否在有效范围内)、排序等场景。

isBefore(LocalDate other) - 判断是否在指定日期之前

用于判断当前日期是否在另一个日期之前,返回 boolean 类型结果(true 表示当前日期在参数日期之前,false 则表示不满足)。

方法参数与返回值:

  • 参数:other(LocalDate 类型),表示要比较的另一个日期。

  • 返回值:boolean 值,true 当且仅当当前日期严格早于 other 日期,否则为 false(包括等于的情况)。

注意:

(1)仅当当前日期在参数日期的 “之前”(即更早)时返回 true,若两个日期相等则返回 false。

(2)仅基于年、月、日进行比较,不涉及任何时间信息,与包含时间的 LocalDateTime 比较逻辑不同。

(3)参数为 null 时会抛出 NullPointerException,实际使用中需确保参数非空或提前判断。

示例:

import java.time.LocalDate;

public class LocalDateIsBeforeExample {
    public static void main(String[] args) {
        // 基础日期:2024-05-20
        LocalDate baseDate = LocalDate.of(2024, 5, 20);
        
        // 1. 比较当前日期是否在之前(参数日期更晚)
        LocalDate laterDate = LocalDate.of(2024, 5, 21);
        boolean isBefore1 = baseDate.isBefore(laterDate);
        System.out.println(baseDate + " 是否在 " + laterDate + " 之前?" + isBefore1); // true
        
        // 2. 比较当前日期是否在之前(参数日期更早)
        LocalDate earlierDate = LocalDate.of(2024, 5, 19);
        boolean isBefore2 = baseDate.isBefore(earlierDate);
        System.out.println(baseDate + " 是否在 " + earlierDate + " 之前?" + isBefore2); // false
        
        // 3. 比较相等的日期
        LocalDate sameDate = LocalDate.of(2024, 5, 20);
        boolean isBefore3 = baseDate.isBefore(sameDate);
        System.out.println(baseDate + " 是否在 " + sameDate + " 之前?" + isBefore3); // false
        
        // 4. 跨月/跨年比较
        LocalDate nextMonth = LocalDate.of(2024, 6, 1);
        LocalDate lastYear = LocalDate.of(2023, 12, 31);
        
        System.out.println(baseDate + " 是否在 " + nextMonth + " 之前?" + baseDate.isBefore(nextMonth)); // true
        System.out.println(baseDate + " 是否在 " + lastYear + " 之前?" + baseDate.isBefore(lastYear)); // false
    }
}

运行结果:

2024-05-20 是否在 2024-05-21 之前?true
2024-05-20 是否在 2024-05-19 之前?false
2024-05-20 是否在 2024-05-20 之前?false
2024-05-20 是否在 2024-06-01 之前?true
2024-05-20 是否在 2023-12-31 之前?false

注意事项:

  • isAfter(LocalDate other) 用于判断当前日期是否在参数日期之后,两者逻辑相反。

  • 若需判断两个日期是否完全相同,应使用 isEqual(LocalDate other) 方法(如 date1.isEqual(date2))。

  • 常用于日期范围校验(如判断某个日期是否在有效区间内)、排序逻辑等。

isLeapYear() - 判断是否为闰年

用于判断当前日期所在的年份是否为闰年,返回 boolean 类型结果(true 表示闰年,false 表示平年)。

遵循公历闰年规则进行判断,闰年规则如下:

  • 能被 4 整除,但不能被 100 整除的年份是闰年(如 2024 年)。

  • 能被 400 整除的年份是闰年(如 2000 年)。

  • 其他情况为平年(如 2023 年、1900 年)。

示例:

import java.time.LocalDate;

public class LocalDateIsLeapYearExample {
    public static void main(String[] args) {
        // 1. 判断当前年份是否为闰年
        LocalDate today = LocalDate.now();
        boolean isCurrentLeap = today.isLeapYear();
        System.out.println(today.getYear() + "年是否为闰年?" + isCurrentLeap); // 如2024年返回true

        // 2. 测试能被4整除但不能被100整除的年份(闰年)
        LocalDate date2024 = LocalDate.of(2024, 3, 1);
        System.out.println("2024年是否为闰年?" + date2024.isLeapYear()); // true

        // 3. 测试能被400整除的年份(闰年)
        LocalDate date2000 = LocalDate.of(2000, 5, 10);
        System.out.println("2000年是否为闰年?" + date2000.isLeapYear()); // true

        // 4. 测试能被100整除但不能被400整除的年份(平年)
        LocalDate date1900 = LocalDate.of(1900, 12, 31);
        System.out.println("1900年是否为闰年?" + date1900.isLeapYear()); // false

        // 5. 测试不能被4整除的年份(平年)
        LocalDate date2023 = LocalDate.of(2023, 2, 28);
        System.out.println("2023年是否为闰年?" + date2023.isLeapYear()); // false
    }
}

运行结果:

2025年是否为闰年?false
2024年是否为闰年?true
2000年是否为闰年?true
1900年是否为闰年?false
2023年是否为闰年?false

注意,闰年的 2 月有 29 天,平年的 2 月只有 28 天。可结合 lengthOfMonth() 方法验证:

LocalDate feb2024 = LocalDate.of(2024, 2, 1);
System.out.println("2024年2月天数:" + feb2024.lengthOfMonth()); // 29(闰年)

LocalDate feb2023 = LocalDate.of(2023, 2, 1);
System.out.println("2023年2月天数:" + feb2023.lengthOfMonth()); // 28(平年)

该方法仅依赖年份,因此同一公历年份内的所有日期调用此方法会返回相同结果。例如,2024-01-01 和 2024-12-31 的 isLeapYear() 结果均为 true。

  

总结

LocalDate 提供了清晰、直观的日期处理方法,避免了传统日期类的线程安全问题和设计缺陷。其不可变特性使得它在多线程环境中使用更加安全,同时丰富的方法也简化了日期计算、比较等常见操作。在处理仅需日期(不含时间)的场景时,LocalDate 是首选的类。

 

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号