杰瑞科技汇

Java如何准确计算两个日期间的天数?

在 Java 中计算两个日期之间的天数,有多种方法,适用于不同的 Java 版本和场景,下面我将介绍几种最常用和推荐的方法。

Java如何准确计算两个日期间的天数?-图1
(图片来源网络,侵删)

使用 Java 8 的 java.time 包 (推荐)

这是目前最现代、最推荐的方法。java.time API 自 Java 8 引入,它设计优秀,线程安全,并且功能强大。

我们将使用 LocalDate 类来表示一个日期(不包含时间),然后使用 ChronoUnit 来计算它们之间的天数差。

计算两个日期之间的完整天数

这个方法会计算从 date1date2 之间完整的天数,从 2025-10-26 00:00 到 2025-10-27 00:00 是 1 天。

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
public class DaysBetweenJava8 {
    public static void main(String[] args) {
        // 定义两个日期
        LocalDate date1 = LocalDate.of(2025, 10, 26);
        LocalDate date2 = LocalDate.of(2025, 11, 15);
        // 使用 ChronoUnit.DAYS.between() 计算天数差
        // 结果是一个 long 类型的整数
        long daysBetween = ChronoUnit.DAYS.between(date1, date2);
        System.out.println("日期 1: " + date1);
        System.out.println("日期 2: " + date2);
        System.out.println("两个日期之间的天数差: " + daysBetween); // 输出: 20
    }
}

计算两个日期之间的“日历”天数

有时候我们关心的是“跨越了多少天”,而不是完整的天数,从 2025-10-26 到 2025-10-27,无论几点,都算作 1 天,这种情况下,我们可以使用 until 方法。

Java如何准确计算两个日期间的天数?-图2
(图片来源网络,侵删)
import java.time.LocalDate;
public class CalendarDaysBetween {
    public static void main(String[] args) {
        LocalDate date1 = LocalDate.of(2025, 10, 26);
        LocalDate date2 = LocalDate.of(2025, 11, 15);
        // 使用 until 方法计算日历天数
        // date1.until(date2) 返回一个 Period 对象
        // 然后调用 getDays() 获取天数
        long calendarDays = date1.until(date2).getDays();
        System.out.println("日期 1: " + date1);
        System.out.println("日期 2: " + date2);
        System.out.println("日历天数差: " + calendarDays); // 输出: 20
        // 另一种写法,效果相同
        long calendarDays2 = date2.until(date1).getDays(); // 会得到负数
        System.out.println("日历天数差 (反向): " + calendarDays2); // 输出: -20
    }
}

注意ChronoUnit.DAYS.between()LocalDate.until().getDays() 在处理纯日期(LocalDate)时,结果通常是相同的。ChronoUnit 的方法更通用,可以用于计算其他时间单位(如小时、分钟)。


使用 java.util.Datejava.util.Calendar (旧方法)

在 Java 8 之前,我们通常使用 DateCalendar 类,这种方法比较繁琐,Date 类本身有很多设计缺陷(例如它同时包含日期和时间,并且不是线程安全的),不推荐在新代码中使用,但了解它有助于维护旧项目。

import java.util.Calendar;
import java.util.Date;
public class DaysBetweenLegacy {
    public static void main(String[] args) {
        // 1. 创建 Calendar 实例
        Calendar calendar1 = Calendar.getInstance();
        Calendar calendar2 = Calendar.getInstance();
        // 2. 设置日期 (注意:月份是从0开始的,0代表一月)
        calendar1.set(2025, Calendar.OCTOBER, 26);
        calendar2.set(2025, Calendar.NOVEMBER, 15);
        // 3. 清除时间部分,只保留日期,否则会影响天数计算
        calendar1.set(Calendar.HOUR_OF_DAY, 0);
        calendar1.set(Calendar.MINUTE, 0);
        calendar1.set(Calendar.SECOND, 0);
        calendar1.set(Calendar.MILLISECOND, 0);
        calendar2.set(Calendar.HOUR_OF_DAY, 0);
        calendar2.set(Calendar.MINUTE, 0);
        calendar2.set(Calendar.SECOND, 0);
        calendar2.set(Calendar.MILLISECOND, 0);
        // 4. 获取 Date 对象并计算毫秒差
        Date date1 = calendar1.getTime();
        Date date2 = calendar2.getTime();
        long diffInMillis = date2.getTime() - date1.getTime();
        // 5. 将毫秒转换为天数
        long daysBetween = diffInMillis / (1000 * 60 * 60 * 24);
        System.out.println("日期 1: " + date1);
        System.out.println("日期 2: " + date2);
        System.out.println("两个日期之间的天数差: " + daysBetween); // 输出: 20
    }
}

缺点

  • 代码冗长,需要手动处理月份和时间的清零。
  • Date 类的设计已过时,容易出错。
  • Calendar 不是线程安全的。

使用 Joda-Time 库 (第三方库)

在 Java 8 之前,Joda-Time 是事实上的标准日期时间库,它比 java.util.Datejava.util.Calendar 好用得多,如果你不能升级到 Java 8,或者在使用遗留项目,Joda-Time 仍然是一个不错的选择。

Java如何准确计算两个日期间的天数?-图3
(图片来源网络,侵删)
import org.joda.time.LocalDate;
import org.joda.time.Days;
public class DaysBetweenJoda {
    public static void main(String[] args) {
        // Joda-Time 的 LocalDate 和 Java 8 的同名类类似
        LocalDate date1 = new LocalDate(2025, 10, 26);
        LocalDate date2 = new LocalDate(2025, 11, 15);
        // 使用 Days 类直接计算
        int daysBetween = Days.daysBetween(date1, date2).getDays();
        System.out.println("日期 1: " + date1);
        System.out.println("日期 2: " + date2);
        System.out.println("两个日期之间的天数差: " + daysBetween); // 输出: 20
    }
}

注意:使用 Joda-Time 需要添加 Maven 或 Gradle 依赖。

<!-- Maven 依赖 -->
<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.12.5</version> <!-- 使用最新版本 -->
</dependency>

总结与对比

方法 优点 缺点 推荐场景
java.time (Java 8+) 现代、API优雅、线程安全、功能强大 需要 Java 8 或更高版本 所有新项目
java.util.Date/Calendar 无需额外库 过时、API繁琐、易出错、非线程安全 维护旧的 Java 7 或更早版本的项目
Joda-Time API优秀,比旧版Java好很多 是第三方库,需要额外依赖 不能升级到 Java 8 的旧项目

最终建议: 对于任何新的 Java 开发,请毫不犹豫地使用 Java 8 的 java.time,它是业界标准,也是最安全、最简洁的选择。

分享:
扫描分享到社交APP
上一篇
下一篇