java项目过程中常用的日期计算工具

createh53个月前 (02-01)技术教程16

在项目开发过程中,日期计算往往是一个非常常见且关键的需求,尤其是在涉及报表生成和数据分析的场景中。许多业务需求需要对日期进行各种复杂的逻辑处理,例如计算某个时间段内的数据、动态生成时间范围、处理跨月或跨年的情况、按周/月/季度等时间维度进行汇总、对比等。这些需求往往不仅仅是简单的日期加减,还涉及到节假日、工作日、闰年等因素的考虑。特别是在报表模块中,日期的正确计算和展示直接影响数据的准确性和用户的决策。为了保证开发效率和准确性,开发人员需要借助一些现成的日期库,或者根据业务需求自定义函数,确保能够灵活处理不同场景下的日期运算。下面提供一些常用的工具:

  1. 获取两个日期之间的日期
  2. 获取某个月的每一周 周一到周五的时间
  3. 获取某个日期的开始时间和结束时间(2024-12-30 00:00:00、2024-12-30 23:59:59)
  4. 获取指定年月的第一天和最后一天
  5. 计算两个日期相差了多少天
  6. 输入一个日期和一个数字,计算出从该日期向前推算的指定天数的日期集合。


获取两个日期之间的日期

/**
     * 获取两个日期之间的日期
     *
     * @param startDate 开始日期
     * @param endDate 截至日期
     * @return 之间的日期
     */
    public static List getDatesBetween(LocalDate startDate, LocalDate endDate) {
        List dates = new ArrayList<>();

        // 使用 while 循环遍历日期
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            dates.add(currentDate);
            currentDate = currentDate.plusDays(1);  // 每次增加一天
        }
        
        return dates;
    }

输出:

[2024-12-10, 2024-12-11, 2024-12-12, 2024-12-13, 2024-12-14, 2024-12-15, 
2024-12-16, 2024-12-17, 2024-12-18, 2024-12-19, 2024-12-20, 2024-12-21, 2024-12-22
, 2024-12-23, 2024-12-24, 2024-12-25, 2024-12-26, 2024-12-27, 2024-12-28
, 2024-12-29, 2024-12-30]


获取某个月的每一周 周一到周五的时间

/**
     * 获取某个月的每一周 周一到周五的时间
     *
     * @param year 指定的年份
     * @param month 指定的月份
     * @return 集合
     */
    public static List> getWeeksOfMonth(int year, int month) {
        // 用于存储每一周的日期集合
        List> weeksList = new ArrayList<>();

        // 获取该月的第一天
        LocalDate firstDayOfMonth = LocalDate.of(year, month, 1);

        // 获取该月的最后一天
        LocalDate lastDayOfMonth = firstDayOfMonth.withDayOfMonth(firstDayOfMonth.lengthOfMonth());

        // 计算该月第一周的周一
        LocalDate currentDay = firstDayOfMonth;

        // 调整为该月第一周的周一
        while (currentDay.getDayOfWeek() != DayOfWeek.MONDAY) {
            currentDay = currentDay.plusDays(1);
        }

        // 遍历每一周
        while (!currentDay.isAfter(lastDayOfMonth)) {
            // 获取该周的周一至周五
            List week = new ArrayList<>();
            for (int i = 0; i < 5; i++) {
                LocalDate day = currentDay.plusDays(i);
                if (!day.isAfter(lastDayOfMonth)) {
                    week.add(day);
                }
            }

            // 将该周的工作日添加到集合中
            weeksList.add(week);

            // 跳到下一周的周一
            currentDay = currentDay.plusWeeks(1);
        }

        return weeksList;
    }

输出

[[2024-12-02, 2024-12-03, 2024-12-04, 2024-12-05, 2024-12-06]
, [2024-12-09, 2024-12-10, 2024-12-11, 2024-12-12, 2024-12-13]
, [2024-12-16, 2024-12-17, 2024-12-18, 2024-12-19, 2024-12-20]
, [2024-12-23, 2024-12-24, 2024-12-25, 2024-12-26, 2024-12-27]
, [2024-12-30, 2024-12-31]]


获取某个日期的开始时间和结束时间(2024-12-30 00:00:00、2024-12-30 23:59:59)

/**
     * 获取某个日期的开始时间和结束时间
     *
     * @param date 传入的日期
     * @return 日期
     */
    public static LocalDateTime[] getStartAndEndOfDay(LocalDate date) {
        // 获取该日期的开始时间 (00:00:00)
        LocalDateTime startOfDay = date.atStartOfDay();

        // 获取该日期的结束时间 (23:59:59)
        LocalDateTime endOfDay = date.atTime(LocalTime.MAX);

        // 返回开始时间和结束时间的数组
        return new LocalDateTime[] { startOfDay, endOfDay };
    }

    /**
     * 获取某个日期的开始时间和结束时间 java.util.date格式
     *
     * @param date 传入的日期
     * @return 日期
     */
    public static Date[] getStartAndEndOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        // 获取该日期的开始时间 (00:00:00)
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date startOfDay = calendar.getTime();

        // 获取该日期的结束时间 (23:59:59)
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        Date endOfDay = calendar.getTime();

        // 返回开始时间和结束时间的数组
        return new Date[] { startOfDay, endOfDay };
    }

输出

 				//调用方式
        LocalDateTime[] startAndEndOfDay = getStartAndEndOfDay(LocalDate.now());
        for (LocalDateTime localDateTime : startAndEndOfDay) {
            System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }

        Date[] startAndEndOfDay1 = getStartAndEndOfDay(new Date());
        for (Date date : startAndEndOfDay1) {
            System.out.println(DateUtil.format(date, DatePattern.NORM_DATETIME_PATTERN));
        }
2024-12-30 00:00:00
2024-12-30 23:59:59
2024-12-30 00:00:00
2024-12-30 23:59:59

获取指定年月的第一天和最后一天

import java.time.LocalDate;
import java.time.YearMonth;

public class DateUtils {
    /**
     * 获取指定年月的第一天和最后一天
     * @param year 年份
     * @param month 月份
     * @return 一个长度为2的数组,索引0为第一天,索引1为最后一天
     */
    public static LocalDate[] getFirstAndLastDayOfMonth(int year, int month) {
        // 创建YearMonth对象
        YearMonth yearMonth = YearMonth.of(year, month);
        
        // 获取该月的第一天
        LocalDate firstDay = yearMonth.atDay(1);
        
        // 获取该月的最后一天
        LocalDate lastDay = yearMonth.atEndOfMonth();
        
        // 返回一个数组,索引0为第一天,索引1为最后一天
        return new LocalDate[] { firstDay, lastDay };
    }

    public static void main(String[] args) {
        int year = 2024;
        int month = 12;

        LocalDate[] firstAndLastDay = getFirstAndLastDayOfMonth(year, month);
        
        System.out.println("First Day: " + firstAndLastDay[0]);
        System.out.println("Last Day: " + firstAndLastDay[1]);
    }
}

输出

First Day: 2024-12-01
Last Day: 2024-12-31

计算两个日期相差了多少天

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

public class DateUtils {

    /**
     * 计算两个日期相差的天数
     * @param startDate 起始日期
     * @param endDate 结束日期
     * @return 两个日期之间相差的天数
     */
    public static long calculateDaysBetween(LocalDate startDate, LocalDate endDate) {
        // 使用ChronoUnit.DAYS.between()来计算日期差
        return ChronoUnit.DAYS.between(startDate, endDate);
    }

    public static void main(String[] args) {
        // 示例:计算2024年1月1日和2024年12月31日之间的天数差
        LocalDate startDate = LocalDate.of(2024, 1, 1);
        LocalDate endDate = LocalDate.of(2024, 12, 31);

        long daysBetween = calculateDaysBetween(startDate, endDate);
        System.out.println("Days Between: " + daysBetween);
    }
}

输出


Days Between: 365

输入一个日期和一个数字,计算出从该日期向前推算的指定天数的日期集合。

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

public class DateUtils {

    /**
     * 获取指定日期之前的日期集合
     * @param startDate 起始日期
     * @param daysCount 向前推算的天数
     * @return 向前推算的日期集合
     */
    public static List getDatesBefore(LocalDate startDate, int daysCount) {
        List dateList = new ArrayList<>();
        
        // 从startDate开始,向前推算daysCount天
        for (int i = 0; i < daysCount; i++) {
            startDate = startDate.minusDays(1);  // 向前推算一天
            dateList.add(startDate);  // 将日期添加到列表
        }
        
        return dateList;
    }

    public static void main(String[] args) {
        // 示例:从2024年12月31日开始,获取过去5天的日期集合
        LocalDate startDate = LocalDate.of(2024, 12, 31);
        int daysCount = 5;

        List datesBefore = getDatesBefore(startDate, daysCount);
        
        // 打印结果
        System.out.println("Dates before " + startDate + ":");
        for (LocalDate date : datesBefore) {
            System.out.println(date);
        }
    }
}

输出:

Dates before 2024-12-31:
2024-12-30
2024-12-29
2024-12-28
2024-12-27
2024-12-26

相关文章

「Java工具类」java8时间日期工具类,整个项目有它就足够了

介绍语本头条号主要是Java常用关键技术点,通用工具类的分享;以及springboot+springcloud+Mybatisplus+druid+mysql+redis+swagger+maven+...

时间戳用法详解,时间与时间戳怎么转换

在程序开发者用到的必不可少的功能就是时间戳与时间的转换了,经常数据库存的是时间戳,但是给用户需要显示具体时间,今天这篇文章就来介绍下怎么使用python,java,JavaScript,php几种语言...

时间管理大师:Java DateTimeFormatter.ofPattern 的幽默指南

前言在这个快节奏的世界里,时间就像一张消费券,谁都想把它花得更值!想象一下,能够像一个时间管理大师一样,随心所欲地掌控每一秒。Java 的 DateTimeFormatter.ofPattern 就是...

打通 JAVA 与内核系列之 一 ReentrantLock 锁的实现原理

写JAVA代码的同学都知道,JAVA里的锁有两大类,一类是synchronized锁,一类是concurrent包里的锁(JUC锁)。其中synchronized锁是JAVA语言层面提供的能力,在此不...

JAVA与PHP语言时间戳的转换问题(java时间转时间戳)

简单描述一下时间戳定义:百度百科:时间戳(timestamp),通常是一个字符序列,唯一的标识某一刻的时间。在编程语言中,时间戳表示自 1970 年 1 月 1 日(08:00:00 GMT) 年至当...

分享一个小技巧——mysql统一处理创建时间和更新时间

背景mysql数据库表设计的时候,通常都会有这两个字段————创建时间和更新时间,创建时间即mysql记录第一次插入的时间,更新时间即mysql记录发生更新时的时间。通常的做法都是先创建对象,然后分别...