LocalDate 是 Java 8 引入的不可变纯日期类,用于处理“年-月-日”,支持 now()、of()、parse() 创建,plus/minus/with 调整,ChronoUnit/Period 计算间隔,isAfter/isBefore 等校验,且原生兼容 JDBC 与 Jackson。

LocalDate 是 Java 8 引入的新日期时间 API 中专用于处理“年-月-日”这一纯日期概念的核心类,不包含时间、时区信息,适合生日、合同生效日、报表截止日等无需精确到小时分钟的业务场景。
创建 LocalDate 实例
避免使用已废弃的 new Date() 或 Calendar,推荐以下安全、直观的方式:
- 当前日期:用 LocalDate.now() —— 基于系统默认时区获取当天日期(注意:它只取日期部分,不关心具体时刻)
- 指定年月日:用 LocalDate.of(2025, 4, 12) 或 LocalDate.of(2025, Month.APRIL, 12) —— 自动校验闰年、大小月,非法日期(如 2025-02-30)会抛 DateTimeException
- 从字符串解析:用 LocalDate.parse("2025-04-12")(默认 ISO_LOCAL_DATE 格式 yyyy-MM-dd);若格式不同(如 "12/04/2025"),需传入 DateTimeFormatter:LocalDate.parse("12/04/2025", DateTimeFormatter.ofPattern("dd/MM/yyyy"))
常见日期计算与调整
LocalDate 是不可变对象,所有“修改”操作都返回新实例,原对象保持不变:
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
- 加减天数/月份/年份:用 plusDays(7)、minusMonths(3)、plusYears(1) —— 比手动算更可靠(例如 2024-01-31.plusMonths(1) 得到 2024-02-29,不是 2024-02-31)
- 调整到特定日期特征:用 with(TemporalAdjusters.firstDayOfMonth()) 获取当月第一天;with(TemporalAdjusters.next(DayOfWeek.MONDAY)) 获取下一个周一;也可自定义逻辑,如 withDayOfMonth(15) 强制设为每月 15 日(若当月无 15 日则抛异常)
- 计算间隔:用 ChronoUnit.DAYS.between(startDate, endDate) 获取两个 LocalDate 之间的天数差(结果可为负);需要年月日分别差值时,用 Period.between(start, end) 返回 Period 对象,再调用 getYears()、getMonths()、getDays()
业务校验与比较
纯日期判断应直接使用 LocalDate 提供的方法,语义清晰且线程安全:
立即学习“Java免费学习笔记(深入)”;
- 是否在某个范围:用 isAfter(other)、isBefore(other)、isEqual(other) —— 比 compareTo() 更易读;组合使用可写 date.isAfter(start) && date.isBefore(end) 表示“在区间内”(注意边界是否包含需自行处理)
- 是否为今天/周末/工作日:用 isEqual(LocalDate.now()) 判断是否今日;用 getDayOfWeek() 返回 DayOfWeek 枚举,再判断 dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY
- 合法性检查:比如合同签署日不能晚于生效日,直接 signDate.isBefore(effectiveDate) || signDate.isEqual(effectiveDate) 即可,无需转毫秒或字符串比较
与旧 API 和数据库交互
迁移或集成时注意类型转换:
- 转为 java.util.Date:需借助 Instant,例如 localDate.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli() 转成毫秒再构造 Date(但通常不推荐,优先用新 API)
- JDBC 数据库存取:现代 JDBC 驱动(如 PostgreSQL 42.2+、MySQL 8.0+)原生支持 LocalDate,PreparedStatement 可直接 setObject(1, localDate),ResultSet 可直接 getObject("date_col", LocalDate.class)
- JSON 序列化(如 Jackson):添加 @JsonFormat(pattern = "yyyy-MM-dd") 注解,或全局配置日期格式,避免默认输出为数组

















