localdate 不能直接转 date,需通过 instant 中转并显式指定时区;localdatetime.parse() 需符合 iso 格式(含 t)或自定义格式器;低版本 jdbc 驱动不支持 localdatetime;推荐使用 plusdays() 等直观方法而非 chronounit。

LocalDate 不能直接转成 Date,别硬 cast
Java 8 的 LocalDate 和老式 Date 是完全不同的类型,没有继承关系。你写 (Date) localDate 会编译失败;用 localDate.toString() 再 parse 更是埋雷——时区、格式、线程安全全不管。
- 真正要互转,得走
Instant中转:比如localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()得到Instant,再用Date.from(instant) -
LocalDate本身不含时间,所以“当天零点”这个语义必须显式指定时区,否则atStartOfDay()默认用系统时区,测试机和生产机时区不一致就出错 - 如果只是存日期(比如生日、合同生效日),坚持用
LocalDate,别转Date—— 后者带时分秒+时区,纯属信息污染
LocalDateTime.parse() 报 DateTimeParseException?检查字符串里有没有 T
LocalDateTime.parse("2023-10-05 14:30:45") 默认会失败,因为标准 ISO 格式要求 T 分隔日期和时间,即 "2023-10-05T14:30:45"。没 T 就是格式不匹配,不是“少秒”或“时区问题”。
- 要么改字符串:
"2023-10-05T14:30:45" - 要么自定义格式器:
LocalDateTime.parse("2023-10-05 14:30:45", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) - 注意
DateTimeFormatter不是线程安全的,别在类里声明 static final 然后多线程共用——用DateTimeFormatter.ofPattern()每次新建更稳妥
数据库里存 LocalDateTime,JDBC 驱动版本低于 4.2 就会丢精度或报错
MySQL Connector/J 4.2 之前版本不识别 LocalDateTime,JDBC 会把它当 Object 处理,可能抛 SQLException: Cannot convert class java.time.LocalDateTime to SQL type,或者默默转成字符串导致排序/查询异常。
- 确认驱动版本:
mysql-connector-java≥ 5.1.38 或 ≥ 6.0.2(推荐用 8.0.x) - JPA 用户注意:Hibernate 5.2+ 原生支持
LocalDateTime;若用旧版,得手动注册AttributeConverter - PostgreSQL 用户相对省心,
timestamp without time zone字段可直存LocalDateTime,但别误用timestamptz——它对应的是ZonedDateTime或带时区的Instant
加减天数用 plusDays(),别用 plus(1, ChronoUnit.DAYS)
两者结果一样,但 plusDays() 更直观、性能略好(跳过单位解析),且 IDE 能更好推导类型。更重要的是,plus(1, ChronoUnit.DAYS) 容易被误写成 plus(1, ChronoUnit.HOURS),而后者在日期计算中几乎从不出现,属于隐蔽 typo。
立即学习“Java免费学习笔记(深入)”;
-
localDate.plusDays(7)清晰表达“一周后” -
localDateTime.minusMonths(1)比minus(1, ChronoUnit.MONTHS)更常见也更安全——月份长度不固定,API 内部已处理月末对齐逻辑 - 避免混用:不要对
LocalDateTime调用plusWeeks()(不存在),它只有plusDays()/plusMonths()等具体单位方法










