跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

如何使用 LocalDate 获取当前年月日并进行加减计算

LocalDate.now()是最安全的获取当前日期方式,直接返回系统默认时区下的纯日期对象,避免可变性与时区陷阱;需指定时区时应显式传入Clock,测试中须用fixed Clock注入固定时间。 LocalDate.now() 是最安全的获取当前日期方式
LocalDate.now()
直接返回系统默认时区下的纯日期对象,不含时间、不依赖
System.currentTimeMillis()
手动构造,也避免了
new Date()
或
Calendar.getInstance()
带来的可变性和时区陷阱。它内部用的是
Clock.systemDefaultZone()
,所以只要 JVM 时区设置正确,结果就可靠。 不要手动拼字符串再解析(比如
"2024-05-20"
→
LocalDate.parse()
),既多余又容易因格式错报
DateTimeParseException
如果需要指定时区(比如业务强制走 UTC),得显式传入
Clock
:
LocalDate.now(Clock.systemUTC())
在单元测试中,别让测试依赖真实系统时间——用
LocalDate.now(Clock.fixed(...))
注入固定时间点 加减天数用 plusDays/minusDays,别碰 withDayOfMonth
plusDays()
和
minusDays()
是语义清晰、边界安全的操作。比如今天是 3 月 31 日,
plusDays(1)
自动进到 4 月 1 日;而
withDayOfMonth(32)
会直接抛
DateTimeException
,因为 3 月没有 32 号。 加减月份用
plusMonths()
/
minusMonths()
,它会自动处理“1 月 31 日 + 1 个月 = 2 月 28 日(或 29 日)”这类逻辑 避免混用:不要对
LocalDate
调用
plusHours()
(不存在),那是
LocalDateTime
的方法 性能上无差别,但可读性差的写法(如
plus(Period.ofDays(5))
)没必要,除非后续要复用
Period
对象 计算两个 LocalDate 之间相差多少天用 ChronoUnit.DAYS.between
ChronoUnit.DAYS.between(start, end)
返回的是整数天数差,包含起始日但不包含结束日(左闭右开),结果可正可负。这是唯一推荐的跨日期天数计算方式。 别用
end.toEpochDay() - start.toEpochDay()
虽然结果一样,但可读性差,且隐藏了“为什么是 epoch day”的认知负担
Period.between(start, end)
返回的是年月日三段式对象,如果只关心总天数,反而多绕一层,还可能因闰年/大小月导致误解(比如
Period
不保证
getDays()
是总天数) 注意参数顺序:
between(earlier, later)
得正数;反过来就是负数,别靠注释猜逻辑 LocalDate 运算后不能忽略「不可变性」这个前提 所有
plusXXX
、
minusXXX
、
withXXX
方法都返回新对象,原变量不变。这是最容易漏掉的一环,尤其从老 Java 习惯转过来的人。 错误写法:
date.plusDays(7); // date 没变!
正确写法:
date = date.plusDays(7);
在流式调用里也要小心:
date.plusMonths(1).minusDays(2)
没问题,但中间没赋值的话,第一步的结果就丢了 如果在循环里反复运算,记得每次接收返回值,否则等于白算 LocalDate 看似简单,但真正卡住人的地方往往不是语法,而是对「不可变」和「语义操作」的下意识忽略——比如以为
withYear(2025)
是“把今年改成 2025”,其实它只改年份,其他字段照搬,3 月 31 日变成 2025 年 3 月 31 日没问题,但 2 月 30 日就会炸。

相关文章