在 Java 中获取给定日期的前一天日期,有几种常见的方法,适用于不同的 Java 版本,我会从最推荐、最现代的方法开始,并介绍一些兼容旧版本的方法。
推荐方法:使用 Java 8+ 的 java.time API (现代且强大)
自 Java 8 引入 java.time 包后,这成为了处理日期和时间的官方标准,它比旧的 Date 和 Calendar 类更安全、更易用。
示例 1:使用 LocalDate (最常用)
LocalDate 表示一个不带时区的日期(如 2025-10-27),非常适合处理日常的日期计算。
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class PreviousDayExample {
public static void main(String[] args) {
// 1. 获取今天的日期
LocalDate today = LocalDate.now();
System.out.println("今天的日期: " + today);
// 2. 获取昨天的日期
LocalDate yesterday = today.minusDays(1);
System.out.println("昨天的日期: " + yesterday);
// 3. 如果你有特定的日期字符串,可以先解析
String specificDateStr = "2025-12-25";
LocalDate specificDate = LocalDate.parse(specificDateStr);
LocalDate dayBeforeSpecific = specificDate.minusDays(1);
System.out.println("在 " + specificDate + " 的前一天是: " + dayBeforeSpecific);
// 4. 格式化输出
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
System.out.println("格式化后的昨天日期: " + yesterday.format(formatter));
}
}
输出:
今天的日期: 2025-10-27
昨天的日期: 2025-10-26
在 2025-12-25 的前一天是: 2025-12-24
格式化后的昨天日期: 2025年10月26日
示例 2:处理带时区的日期 (ZonedDateTime)
如果你的日期和时间与时区相关(来自数据库的 TIMESTAMP WITH TIME ZONE),应该使用 ZonedDateTime。
import java.time.ZonedDateTime;
import java.time.ZoneId;
public class PreviousDayWithZoneExample {
public static void main(String[] args) {
// 获取当前时区的日期时间
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
System.out.println("当前上海时间: " + now);
// 获取前一天的同时间点
ZonedDateTime yesterdaySameTime = now.minusDays(1);
System.out.println("前一天的同时间点: " + yesterdaySameTime);
}
}
兼容旧版本的方法 (Java 8 之前)
如果你正在维护一个旧项目,不能使用 Java 8,那么可以使用 java.util.Calendar。注意:java.util.Date 本身有设计缺陷,通常不推荐直接用于日期计算。
示例:使用 Calendar
Calendar 是一个更灵活但也更复杂的类。
import java.util.Calendar;
import java.util.Date;
import java.text.SimpleDateFormat;
public class PreviousDayLegacyExample {
public static void main(String[] args) {
// 1. 创建一个 Calendar 实例并设置为当前时间
Calendar calendar = Calendar.getInstance();
// 2. 获取当前日期并打印
Date today = calendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println("今天的日期: " + sdf.format(today));
// 3. 将日期减去一天
calendar.add(Calendar.DAY_OF_MONTH, -1);
// 4. 获取计算后的日期
Date yesterday = calendar.getTime();
System.out.println("昨天的日期: " + sdf.format(yesterday));
// 5. 如果你想从特定日期开始计算
Calendar specificCalendar = Calendar.getInstance();
specificCalendar.set(2025, Calendar.DECEMBER, 25); // 月份是从0开始的,11月是10,12月是11
specificCalendar.add(Calendar.DAY_OF_MONTH, -1);
Date dayBeforeSpecific = specificCalendar.getTime();
System.out.println("在 2025-12-25 的前一天是: " + sdf.format(dayBeforeSpecific));
}
}
重要提示:
Calendar的月份是从0开始的(0=一月,1=二月, ...,11=十二月),这是一个非常常见的错误来源。Date类的很多方法已经被废弃,并且它包含时间信息,在只处理日期时容易出错。
总结与对比
| 方法 | 类/接口 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|---|
LocalDate.minusDays(1) |
java.time.LocalDate |
API直观、线程安全、不可变、功能强大 | 需要 Java 8 或更高版本 | 所有新项目,首选方案 |
Calendar.add(Calendar.DAY_OF_MONTH, -1) |
java.util.Calendar |
兼容旧版本(Java 8前) | API繁琐、可变、月份从0开始、容易出错 | 维护旧项目,无法升级Java版本时 |
Date 相关计算 |
java.util.Date |
非常古老,几乎所有环境都支持 | 设计有缺陷,可变,包含时间信息,API不直观 | 不推荐,仅存在于非常古老的代码中 |
对于任何新的 Java 开发,请务必使用 java.time 包。LocalDate 是处理日期(不包含时间)的理想选择,其 minusDays() 方法是获取前一天日期最简洁、最安全的方式,只有在无法使用 Java 8 的情况下,才考虑使用 Calendar。
