You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算两个日期的小数月差值(Scala或Java)

计算两个日期之间的精确月份差值(含小数)

实现思路

要得到符合日历规则的带小数月份差值,需要拆分三部分计算:

  • 完整的整数月份数
  • 起始日期所在月剩余天数的占比
  • 结束日期所在月已过天数的占比
  • 中间完整月份直接按1个月计算(每个完整月对应1份)

具体执行步骤:

  1. 先判断日期顺序,确保起始日期早于或等于结束日期,避免负数结果
  2. 计算近似完整月份数,再根据日部分调整得到真实的完整月份数
  3. 分别计算起始月剩余天数占比、结束月已过天数占比,与完整月份数相加得到最终结果

代码实现

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

public class MonthDiffCalculator {
    public static double calculateExactMonthDifference(LocalDate d1, LocalDate d2) {
        // 处理日期顺序,保证d1为较早日期
        if (d1.isAfter(d2)) {
            return -calculateExactMonthDifference(d2, d1);
        }

        // 计算近似完整月份数
        long approxFullMonths = ChronoUnit.MONTHS.between(d1, d2);
        LocalDate tempDate = d1.plusMonths(approxFullMonths);

        // 若tempDate晚于d2,说明完整月份数需减1
        if (tempDate.isAfter(d2)) {
            approxFullMonths--;
            tempDate = d1.plusMonths(approxFullMonths);
        }

        double monthDiff = approxFullMonths;

        // 计算起始月剩余天数的占比(仅当tempDate不在d1当月时)
        if (!YearMonth.from(d1).equals(YearMonth.from(tempDate))) {
            int daysInStartMonth = YearMonth.from(d1).lengthOfMonth();
            int remainingDaysInStartMonth = daysInStartMonth - d1.getDayOfMonth();
            monthDiff += (double) remainingDaysInStartMonth / daysInStartMonth;
        }

        // 计算结束月已过天数的占比
        int daysInEndMonth = YearMonth.from(d2).lengthOfMonth();
        if (YearMonth.from(tempDate).equals(YearMonth.from(d2))) {
            // 同月份时,直接计算天数差的占比
            int daysPassed = d2.getDayOfMonth() - tempDate.getDayOfMonth();
            monthDiff += (double) daysPassed / daysInEndMonth;
        } else {
            // 不同月份时,直接取结束日占当月天数的比例
            monthDiff += (double) d2.getDayOfMonth() / daysInEndMonth;
        }

        return monthDiff;
    }

    public static void main(String[] args) {
        LocalDate d1 = LocalDate.of(1999, 5, 12);
        LocalDate d2 = LocalDate.of(1999, 8, 24);
        double diff = calculateExactMonthDifference(d1, d2);
        System.out.printf("日期%s到%s的月份差值为:%.3f%n", d1, d2, diff);
    }
}

代码说明

  • 基于java.time现代日期API实现,避免旧Date/Calendar类的线程安全与计算误差问题
  • 自动适配日期顺序,支持正向、反向差值计算
  • 通过YearMonth.lengthOfMonth()获取对应年月的实际天数,自动处理闰年、不同月份的天数差异
  • 完全按照日历规则拆分计算,确保结果精确符合需求

内容的提问来源于stack exchange,提问作者user17931591

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 07:55:20