日期时间计算技巧

计算两个日期的差值(天 / 月 / 年)

使用 java.time.temporal.ChronoUnit 枚举或 Period 类可快速计算日期差。例如:

package com.hxstrive.java_date_time.calculate;

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

public class DateDifference {
    public static void main(String[] args) {
        LocalDate start = LocalDate.of(2023, 1, 15);
        LocalDate end = LocalDate.of(2024, 3, 20);

        // 1. 使用 ChronoUnit 直接计算单个单位差值
        long days = ChronoUnit.DAYS.between(start, end);
        long months = ChronoUnit.MONTHS.between(start, end);
        long years = ChronoUnit.YEARS.between(start, end);
        
        System.out.println("相差天数: " + days);
        System.out.println("相差月数: " + months);
        System.out.println("相差年数: " + years);
        
        // 2. 使用 Period 获取完整的年月日差值
        Period period = Period.between(start, end);
        System.out.printf("相差 %d年%d月%d天%n", 
                         period.getYears(), 
                         period.getMonths(), 
                         period.getDays());
    }
}

运行结果:

相差天数: 430
相差月数: 14
相差年数: 1
相差 1年2月5天

注意:

  • ChronoUnit 计算的是两个日期之间的完整单位数(如月份差会忽略不足一个月的天数)

  • Period 会拆分出完整的年、月、日差值(更贴近人类对时间差的理解)

  

获取当月 / 当年的第一天和最后一天

利用 TemporalAdjusters 工具类可快速定位特殊日期。例如:

package com.hxstrive.java_date_time.calculate;

import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;

public class BoundaryDates {
    public static void main(String[] args) {
        LocalDate today = LocalDate.of(2023, 10, 5);
        
        // 当月第一天
        LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
        // 当月最后一天
        LocalDate lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
        
        // 当年第一天
        LocalDate firstDayOfYear = today.with(TemporalAdjusters.firstDayOfYear());
        // 当年最后一天
        LocalDate lastDayOfYear = today.with(TemporalAdjusters.lastDayOfYear());
        
        System.out.println("当月第一天: " + firstDayOfMonth);  // 2023-10-01
        System.out.println("当月最后一天: " + lastDayOfMonth);  // 2023-10-31
        System.out.println("当年第一天: " + firstDayOfYear);    // 2023-01-01
        System.out.println("当年最后一天: " + lastDayOfYear);    // 2023-12-31
    }
}

运行结果:

当月第一天: 2023-10-01
当月最后一天: 2023-10-31
当年第一天: 2023-01-01
当年最后一天: 2023-12-31

注意,还可通过 firstDayOfNextMonth() 获取下月第一天,通过 dayOfWeekInMonth(n, DayOfWeek.MONDAY) 获取当月第 n 个周一。

  

计算某个日期之后的第一个工作日(排除周末和节假日)

需要自定义排除周六、周日及法定节假日的逻辑。例如:

package com.hxstrive.java_date_time.calculate;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;

public class WorkingDayCalculator {
    // 模拟节假日(实际应用中可从配置或数据库加载)
    private static final Set<LocalDate> HOLIDAYS;
    static {
        HOLIDAYS = new HashSet<>();
        HOLIDAYS.add(LocalDate.of(2023, 10, 1));  // 国庆节
        HOLIDAYS.add(LocalDate.of(2023, 10, 2));
        HOLIDAYS.add(LocalDate.of(2023, 10, 3));
    }
    
    /**
     * 获取指定日期之后的第一个工作日
     * @param date 基准日期
     * @return 第一个工作日
     */
    public static LocalDate getFirstWorkingDayAfter(LocalDate date) {
        LocalDate candidate = date.plusDays(1);  // 从第二天开始检查
        
        while (true) {
            // 检查是否为周末
            DayOfWeek dayOfWeek = candidate.getDayOfWeek();
            if (dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY) {
                candidate = candidate.plusDays(1);
                continue;
            }
            
            // 检查是否为节假日
            if (HOLIDAYS.contains(candidate)) {
                candidate = candidate.plusDays(1);
                continue;
            }
            
            // 既不是周末也不是节假日,返回
            return candidate;
        }
    }
    
    public static void main(String[] args) {
        LocalDate testDate1 = LocalDate.of(2023, 9, 29);  // 周五
        LocalDate testDate2 = LocalDate.of(2023, 10, 3);  // 国庆假期中
        LocalDate testDate3 = LocalDate.of(2023, 10, 7);  // 周六
        
        System.out.println("9月29日后的第一个工作日: " + getFirstWorkingDayAfter(testDate1));  // 10-04
        System.out.println("10月3日后的第一个工作日: " + getFirstWorkingDayAfter(testDate2));   // 10-04
        System.out.println("10月7日后的第一个工作日: " + getFirstWorkingDayAfter(testDate3));   // 10-09
    }
}

运行结果:

9月29日后的第一个工作日: 2023-10-04
10月3日后的第一个工作日: 2023-10-04
10月7日后的第一个工作日: 2023-10-09

  

  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号