如何在Java中基于指定天数计算目标日期(日、月、年)?
Java实现日期加减天数的两种方式
嘿,这个需求我太熟悉了!在Java里要实现类似Linux Shell date -d "2020-10-19 30 days"的日期加减功能,其实有两种常用方案——取决于你用的Java版本,我给你分别拆解一下:
一、Java 8及以后推荐:使用java.time新日期API(强烈推荐)
Java 8引入的java.time包彻底解决了旧日期API的各种坑(比如线程不安全、月份索引混乱等),用起来简洁又可靠。
示例代码:指定基准日期加减天数
import java.time.LocalDate; import java.time.format.DateTimeFormatter; public class DateCalculator { public static void main(String[] args) { // 1. 定义基准日期字符串和格式 String baseDateStr = "2020-10-19"; DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 2. 解析字符串为LocalDate对象 LocalDate baseDate = LocalDate.parse(baseDateStr, dateFormatter); // 3. 计算目标日期:加30天/减30天 LocalDate dateAfter30Days = baseDate.plusDays(30); LocalDate dateBefore30Days = baseDate.minusDays(30); // 4. 格式化输出结果 System.out.println("30天后的日期: " + dateFormatter.format(dateAfter30Days)); System.out.println("30天前的日期: " + dateFormatter.format(dateBefore30Days)); } }
关键说明:
LocalDate是不可变类,线程安全,调用plusDays()/minusDays()会返回一个新的对象,不会修改原对象- 如果要以当前日期为基准,直接用
LocalDate.now()即可,省去字符串解析步骤 - 如果需要处理带时区的日期,可以用
ZonedDateTime,比如ZonedDateTime.now(ZoneId.of("Asia/Shanghai")),然后同样调用plusDays()方法
二、Java 8之前:使用Calendar和Date旧API(仅用于维护老项目)
如果你的项目还在使用Java 7或更早版本,只能用旧的java.util.Calendar和java.util.Date,但要注意它的坑:
示例代码:
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; public class OldDateCalculator { public static void main(String[] args) throws Exception { // 1. 解析基准日期字符串 String baseDateStr = "2020-10-19"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date baseDate = sdf.parse(baseDateStr); // 2. 用Calendar进行日期加减 Calendar calendar = Calendar.getInstance(); calendar.setTime(baseDate); // 加30天 calendar.add(Calendar.DAY_OF_MONTH, 30); Date dateAfter30Days = calendar.getTime(); // 减30天(这里要注意:Calendar是可变的,所以需要先回到基准日期再减) calendar.add(Calendar.DAY_OF_MONTH, -60); // 因为刚才加了30,所以减60回到基准后再减30 Date dateBefore30Days = calendar.getTime(); // 3. 输出结果 System.out.println("30天后的日期: " + sdf.format(dateAfter30Days)); System.out.println("30天前的日期: " + sdf.format(dateBefore30Days)); } }
注意事项:
Calendar是可变类,线程不安全,多线程环境下要注意同步- 月份是从0开始索引的(1月对应0,12月对应11),容易踩坑
SimpleDateFormat同样不是线程安全的,不要作为全局变量使用
内容的提问来源于stack exchange,提问作者ROH07




