Java计算两个日期相差天数的多种实现方法

追风的人
追风的人
发布时间:2026-10-14 | 2人浏览过
原创

在Java开发中,经常需要计算两个日期之间的天数差,例如物流时效统计或用户留存分析。本文将详细解析从传统 Calendar 到现代 java.time API 的各种实现方法,并提供完整代码示例。

方法一:使用 JDK 8+ java.time API(推荐)

这是目前最推荐的方式。JDK 8 引入了新的日期和时间 API,其中 LocalDate 和 ChronoUnit.DAYS.between 可以极其简洁地完成日期差计算,且线程安全、逻辑清晰。

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class DateDiffExample {
    public static long daysBetween(LocalDate startDate, LocalDate endDate) {
        // ChronoUnit.DAYS.between 自动处理闰年和大小日期顺序
        return ChronoUnit.DAYS.between(startDate, endDate);
    }

    public static void main(String[] args) {
        LocalDate start = LocalDate.parse("2012-12-01");
        LocalDate end = LocalDate.parse("2012-12-12");
        
        long days = daysBetween(start, end);
        System.out.println("相差天数: " + Math.abs(days)); // 输出 11
    }
}

方法二:基于时间戳(毫秒)计算

通过解析日期字符串为 Date 对象,获取其毫秒时间戳,然后相除得到天数。这种方法逻辑简单,但需注意时区和舍入问题(向下取整),通常适用于只需大致天数的场景。

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TimestampDateDiff {
    public static int daysBetween(String dateStr1, String dateStr2) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date d1 = sdf.parse(dateStr1);
        Date d2 = sdf.parse(dateStr2);
        
        // 1秒=1000毫秒, 1分=60秒, 1时=60分, 1天=24时
        long diffInMillis = d2.getTime() - d1.getTime();
        long diffInDays = diffInMillis / (1000 * 3600 * 24);
        
        return (int) diffInDays;
    }

    public static void main(String[] args) throws Exception {
        System.out.println(daysBetween("2012-09-08", "2012-09-15")); // 输出 7
    }
}

方法三:使用旧版 Calendar API(兼容老项目)

对于必须兼容 JDK 7 或更早版本的项目,可以使用 java.util.Calendar。原稿中提供的复杂年份循环算法容易出错,以下提供一个修正后的标准实现,重点在于清除时分秒毫秒,确保只比较“日期”部分。

import java.util.Calendar;
import java.util.GregorianCalendar;

public class CalendarDateDiff {
    /**
     * 计算两个日历对象相差的天数
     */
    public static int daysBetween(Calendar cal1, Calendar cal2) {
        // 克隆以避免修改原对象,并清除时分秒毫秒,只保留日期
        Calendar c1 = (Calendar) cal1.clone();
        c1.set(Calendar.HOUR_OF_DAY, 0);
        c1.set(Calendar.MINUTE, 0);
        c1.set(Calendar.SECOND, 0);
        c1.set(Calendar.MILLISECOND, 0);

        Calendar c2 = (Calendar) cal2.clone();
        c2.set(Calendar.HOUR_OF_DAY, 0);
        c2.set(Calendar.MINUTE, 0);
        c2.set(Calendar.SECOND, 0);
        c2.set(Calendar.MILLISECOND, 0);

        // 将 Calendar 转换为 ZoneAware 的 Instant 或直接使用 getTime().getTime()
        long timeInMillis1 = c1.getTimeInMillis();
        long timeInMillis2 = c2.getTimeInMillis();
        
        long diffMillis = Math.abs(timeInMillis2 - timeInMillis1);
        return (int) (diffMillis / (1000 * 3600 * 24));
    }
}

方法四:使用第三方库 Joda-Time

在 Java 8 之前,joda-time 是处理日期最常用的第三方库。它的 Days.daysBetween() 方法非常直观。虽然 JDK 8 后不再建议新项目引入,但在维护老旧系统时仍会见到。

import org.joda.time.DateTime;
import org.joda.time.Days;

public class JodaTimeExample {
    public static void main(String[] args) {
        DateTime dt1 = new DateTime("2012-12-01");
        DateTime dt2 = new DateTime("2012-12-12");
        
        // 直接获取 Days 对象,再转为整数
        int days = Days.daysBetween(dt1, dt2).getDays();
        System.out.println("相差天数: " + days);
    }
}

总结与注意事项

  • 精度问题:如果使用毫秒法(方法二),注意日期中的时间部分会影响结果。例如 23:00 和 01:00 之间跨了一天,但毫秒差可能不足24小时。建议先将时间归零或使用 LocalDate。
  • 闰年处理:上述推荐方法均自动处理闰年(2月29日),无需手动判断全年是否366天。
  • 库的选择:优先使用 JDK 8+ java.time 包;若需支持 Android 低版本或非主流 JVM,可考虑 ThreeTenABP 或 Joda-Time。
以上就是Java计算两个日期相差天数的详细内容,更多关于Java日期操作的资料请关注本站其它相关文章!
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表