LocalDate、LocalTime、LocalDateTime 本身不可变且线程安全,问题源于误用(如全局共享或误以为可变修改);LocalDateTime.now() 默认依赖系统时区,时区不一致会导致时间错误,应显式指定时区或改用ZonedDateTime;解析需用DateTimeFormatter显式定义格式;存入MySQL需驱动支持并配置时区;跨时区场景应使用ZonedDateTime或UTC时间戳。

LocalDate、LocalTime、LocalDateTime 不是线程安全问题的根源,但它们本身不可变,所以用错场景才出问题——比如当成全局共享状态缓存、或在多线程里反复修改引用却误以为在改对象。
LocalDateTime.now() 为什么有时返回错误时区时间?
它默认用系统默认时区(ZoneId.systemDefault())构造,但不带时区信息;如果系统时区被改过(比如 Docker 容器没配 TZ 环境变量),或服务器和开发机时区不一致,LocalDateTime.now() 看起来就“不准”。
- 生产环境务必显式指定时区:
LocalDateTime.now(ZoneId.of("Asia/Shanghai")) - 更推荐直接用
ZonedDateTime.now(ZoneId.of("Asia/Shanghai")),避免后续做时区转换时漏掉上下文 - Spring Boot 应用可在
application.properties加spring.jackson.time-zone=GMT+8,但这只影响 JSON 序列化,不影响LocalDateTime.now()行为
LocalDate.parse() 报 java.time.format.DateTimeParseException 怎么办?
常见于前端传来的日期字符串格式和解析器默认格式不匹配。例如传 "2023-05-12" 没问题,但传 "12/05/2023" 或 "20230512" 就会炸。
- 别依赖默认格式:
LocalDate.parse("2023-05-12")成功,但LocalDate.parse("2023/05/12")失败 - 必须用
DateTimeFormatter显式声明格式:LocalDate.parse("2023/05/12", DateTimeFormatter.ofPattern("yyyy/MM/dd")) - 注意年份占位符:
yy解析 23 会当成 2023,yyyy才严格按四位;月份用MM(数字),MMM(英文缩写),别混用
LocalDateTime 能不能直接存进 MySQL 的 DATETIME 字段?
可以,但得看 JDBC 驱动版本和配置。MySQL 5.7+ + Connector/J 8.0.22+ 默认支持,旧版本可能自动转成字符串或报错 Cannot convert class java.time.LocalDateTime。
立即学习“Java免费学习笔记(深入)”;
- 确认连接 URL 含
useSSL=false&serverTimezone=GMT%2B8(时区必须显式设,否则驱动可能用客户端时区解析) - MyBatis 中,字段类型用
LocalDateTime,JDBC 类型保持jdbcType="TIMESTAMP"即可,不用手动转Timestamp.valueOf() - Hibernate 5.2+ 原生支持,但若用老版本或自定义 Type,容易把
LocalDateTime当成java.util.Date处理,导致时分秒丢失
最容易被忽略的是:LocalDateTime 没有时区语义,但它在数据库里存的是“本地时间快照”。一旦业务要跨时区显示(比如用户在纽约下单、后台在东京处理),光靠 LocalDateTime 就不够用了——这时候该上 ZonedDateTime 或存 UTC 时间戳。











