LocalDate.now() 返回 JVM 默认时区的当前日期(年-月-日),不包含时间且不受 locale 和 TimeZone.setDefault() 影响;加减天数须用 plusDays()/minusDays(),不可用 with();LocalDate 不可变,操作后需重新赋值。

LocalDate.now() 返回的是什么日期?
LocalDate.now() 获取的是 JVM 所在系统默认时区的当前日期(不包含时间部分),它基于系统时钟,但**不依赖本地时区的午夜偏移计算**,而是直接截取当前时刻对应的年-月-日。这意味着如果你系统时区是 Asia/Shanghai,且此刻是 2024-06-15T14:30:00+08:00,LocalDate.now() 就返回 2024-06-15。
注意:它不读取系统 locale 设置(比如中文/英文月份名),只读取时区和系统时钟;也不受 java.util.TimeZone.setDefault() 影响——因为 LocalDate 是时区中立的,它内部始终通过 Clock.systemDefaultZone() 获取带时区的瞬时值再剥离时间部分。
加减天数必须用 with() 或 plus()/minus()?
不能用 with() 直接加减天数——with() 用于替换字段(如 withYear(2025)),不是算术运算。正确方式是调用 plusDays() 或 minusDays():
LocalDate today = LocalDate.now(); LocalDate tomorrow = today.plusDays(1); LocalDate lastWeek = today.minusDays(7);
这些方法返回新对象(LocalDate 不可变),原对象不变。传入负数也能工作,比如 plusDays(-3) 等价于 minusDays(3),但语义清晰起见,建议正数用 plusXxx,负数用 minusXxx。
- 支持的单位有限:只有
plusDays()、plusWeeks()、plusMonths()、plusYears()及其minus版本;没有plusHours()(那是LocalDateTime的事) - 跨月/年自动处理:比如
LocalDate.of(2024, 1, 31).plusDays(1)得到2024-02-01,不会抛异常 - 性能无差异:所有方法都是 O(1),底层只是对内部的“自纪元以来天数”整型做加减
为什么有时加减后日期“没变”?
最常见原因是误用了可变对象思维,忘了 LocalDate 是不可变的:
LocalDate date = LocalDate.now(); date.plusDays(10); // ❌ 这行没赋值,date 还是原值 System.out.println(date); // 输出仍是今天
正确写法必须重新赋值或链式调用:
LocalDate date = LocalDate.now().plusDays(10); // ✅ // 或 date = date.plusDays(10); // ✅
另一个容易被忽略的点:如果在循环里反复调用 LocalDate.now(),每次都会获取实时系统日期,而不是“基准日期”。例如:
LocalDate










