springboot 工具类 日期时间列表工具类详解:高效处理日期范围的利器
·
日期时间列表工具类详解:高效处理日期范围的利器
在日常开发中,我们经常需要处理各种日期时间相关的业务逻辑,比如生成日期范围、计算时间差、处理闰年等。今天给大家分享一个功能强大的日期时间工具类 DateListUtil,它封装了常见的日期操作,让日期处理变得简单高效。
工具类概述
DateListUtil 是一个专门用于处理日期时间列表的工具类,主要功能包括:
- 生成日期范围内的每一天
- 生成时间范围内的小时列表
- 计算日期时间差
- 处理日期时间的加减操作
- 闰年判断和日期格式化
核心功能详解
1. 生成日期范围列表
/**
* 获取两个日期之间的每一天
* @param beginDate 开始日期 (格式: yyyy-MM-dd)
* @param endDate 结束日期 (格式: yyyy-MM-dd)
* @return 日期字符串列表
*/
public static List<String> getEveryday(String beginDate, String endDate) {
long days = countDay(beginDate, endDate);
int[] ymd = splitYMD(beginDate);
List<String> everyDays = new ArrayList();
everyDays.add(beginDate);
for(int i = 0; (long)i < days; ++i) {
ymd = addOneDay(ymd[0], ymd[1], ymd[2]);
everyDays.add(formatYear(ymd[0]) + "-" + formatMonthDay(ymd[1]) + "-" + formatMonthDay(ymd[2]));
}
return everyDays;
}
使用示例:
List<String> dateList = DateListUtil.getEveryday("2024-01-01", "2024-01-05");
// 返回: ["2024-01-01", "2024-01-02", "2024-01-03", "2024-01-04", "2024-01-05"]
2. 生成小时列表
/**
* 获取两个日期时间之间的小时列表
* @param beginDate 开始时间 (格式: yyyy-MM-dd HH:mm)
* @param endDate 结束时间 (格式: yyyy-MM-dd HH:mm)
* @return 小时字符串列表
*/
public static List<String> getEveryHour(String beginDate, String endDate) {
long hours = countHour(beginDate, endDate);
List<String> everyHours = new ArrayList();
for(int i = 0; (long)i < hours + 1L; ++i) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime now = LocalDateTime.parse(beginDate, formatter);
LocalDateTime oneHourLater = now.plusHours((long)i);
String date = oneHourLater.format(formatter);
int[] ymd = splitYMDH(date);
everyHours.add(formatMonthDay(ymd[3]));
}
return everyHours;
}
使用示例:
List<String> hourList = DateListUtil.getEveryHour("2024-01-01 08:00", "2024-01-01 12:00");
// 返回: ["08", "09", "10", "11", "12"]
3. 时间偏移计算
/**
* 获取指定时间前后的小时时间
* @param beginDate 基准时间
* @param hour 小时数
* @param fal true:加小时, false:减小时
* @return 计算后的时间字符串
*/
public static String getSpecialdHour(String beginDate, Integer hour, boolean fal) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime now = LocalDateTime.parse(beginDate, formatter);
String date;
if (fal) {
LocalDateTime oneHourLater = now.plusHours((long)hour);
date = oneHourLater.format(formatter);
} else {
LocalDateTime oneHourLater = now.minus(Duration.ofHours((long)hour));
date = oneHourLater.format(formatter);
}
return date;
}
使用示例:
// 加3小时
String laterTime = DateListUtil.getSpecialdHour("2024-01-01 10:00", 3, true);
// 返回: "2024-01-01 13:00"
// 减2小时
String earlierTime = DateListUtil.getSpecialdHour("2024-01-01 10:00", 2, false);
// 返回: "2024-01-01 08:00"
4. 时间差计算
// 计算天数差
public static long countDay(String begin, String end) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
long day = 0L;
try {
Date beginDate = format.parse(begin);
Date endDate = format.parse(end);
day = (endDate.getTime() - beginDate.getTime()) / 86400000L;
} catch (ParseException var8) {
var8.printStackTrace();
}
return day;
}
// 计算小时差
public static long countHour(String begin, String end) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
long hour = 0L;
try {
Date beginDate = format.parse(begin);
Date endDate = format.parse(end);
hour = (endDate.getTime() - beginDate.getTime()) / 3600000L;
} catch (ParseException var8) {
var8.printStackTrace();
}
return hour;
}
使用示例:
long days = DateListUtil.countDay("2024-01-01", "2024-01-10"); // 返回: 9
long hours = DateListUtil.countHour("2024-01-01 08:00", "2024-01-01 18:00"); // 返回: 10
技术亮点
1. 混合使用新旧日期API
工具类巧妙地将传统的 SimpleDateFormat 与现代的 LocalDateTime 结合使用:
// 传统API - 用于简单的时间差计算
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date beginDate = format.parse(begin);
// 现代API - 用于复杂的时间操作
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime now = LocalDateTime.parse(beginDate, formatter);
2. 精确的闰年处理
public static boolean isLeapYear(int year) {
return year >= gregorianCutoverYear ?
(year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) :
(year % 4 == 0);
}
// 闰年和平年的每月天数数组
private static final int[] DAYS_P_MONTH_LY = new int[]{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
private static final int[] DAYS_P_MONTH_CY = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
3. 日期分量智能处理
// 拆分年月日
public static int[] splitYMD(String date) {
date = date.replace("-", "").replace(" ", "");
return new int[]{
Integer.parseInt(date.substring(0, 4)), // 年
Integer.parseInt(date.substring(4, 6)), // 月
Integer.parseInt(date.substring(6, 8)) // 日
};
}
// 格式化保证两位数
public static String formatMonthDay(int decimal) {
DecimalFormat df = new DecimalFormat("00");
return df.format((long)decimal);
}
实际应用场景
1. 报表系统
// 生成月度报表的日期范围
public List<Report> generateMonthlyReport(String month) {
String startDate = month + "-01";
String endDate = month + "-31"; // 实际应该计算当月最后一天
List<String> dates = DateListUtil.getEveryday(startDate, endDate);
List<Report> reports = new ArrayList<>();
for (String date : dates) {
Report report = generateDailyReport(date);
reports.add(report);
}
return reports;
}
2. 数据统计
// 统计每小时的访问量
public Map<String, Integer> getHourlyVisitStats(String startTime, String endTime) {
List<String> hours = DateListUtil.getEveryHour(startTime, endTime);
Map<String, Integer> stats = new LinkedHashMap<>();
for (String hour : hours) {
int count = getVisitCountByHour(hour);
stats.put(hour + ":00", count);
}
return stats;
}
3. 任务调度
// 计算任务执行时间
public void scheduleTask(String baseTime, int delayHours) {
String executeTime = DateListUtil.getSpecialdHour(baseTime, delayHours, true);
// 计算任务预计完成时间(假设任务需要2小时)
String estimatedEndTime = DateListUtil.getSpecialdHour(executeTime, 2, true);
scheduleTaskAt(executeTime, estimatedEndTime);
}
使用注意事项
-
日期格式要求
- 日期格式必须为
yyyy-MM-dd - 日期时间格式必须为
yyyy-MM-dd HH:mm
- 日期格式必须为
-
异常处理
- 方法内部捕获了
ParseException,但生产环境建议改进异常处理 - 调用方应确保传入的日期格式正确
- 方法内部捕获了
-
性能考虑
- 对于大数据量的日期范围,建议分批处理
- 频繁调用时注意字符串操作的性能开销
-
线程安全
SimpleDateFormat不是线程安全的,需要注意使用场景
总结
DateListUtil 工具类为我们提供了一套完整的日期时间处理解决方案,具有以下优点:
- 功能全面:覆盖了日常开发中大部分的日期时间处理需求
- 使用简单:方法封装良好,调用方便
- 算法准确:正确处理了闰年、月末等边界情况
- 灵活性强:支持多种日期时间操作场景
无论是报表生成、数据分析还是任务调度,这个工具类都能大大提升开发效率。希望这个工具类能够对大家的项目开发有所帮助!
完整代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.mnsn.framework.boot.utils;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class DateListUtil {
private static transient int gregorianCutoverYear = 1582;
private static final int[] DAYS_P_MONTH_LY = new int[]{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
private static final int[] DAYS_P_MONTH_CY = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
public static final String SHORT_DATE_FORMAT = "yyyy-MM-dd";
private static final int Y = 0;
private static final int M = 1;
private static final int D = 2;
private static final int H = 3;
public DateListUtil() {
}
public static List<String> getEveryday(String beginDate, String endDate) {
long days = countDay(beginDate, endDate);
int[] ymd = splitYMD(beginDate);
List<String> everyDays = new ArrayList();
everyDays.add(beginDate);
for(int i = 0; (long)i < days; ++i) {
ymd = addOneDay(ymd[0], ymd[1], ymd[2]);
String var10001 = formatYear(ymd[0]);
everyDays.add(var10001 + "-" + formatMonthDay(ymd[1]) + "-" + formatMonthDay(ymd[2]));
}
return everyDays;
}
public static List<String> getEveryHour(String beginDate, String endDate) {
long hours = countHour(beginDate, endDate);
List<String> everyHours = new ArrayList();
for(int i = 0; (long)i < hours + 1L; ++i) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime now = LocalDateTime.parse(beginDate, formatter);
LocalDateTime oneHourLater = now.plusHours((long)i);
String date = oneHourLater.format(formatter);
int[] ymd = splitYMDH(date);
everyHours.add(formatMonthDay(ymd[3]));
}
return everyHours;
}
public static String getSpecialdHour(String beginDate, Integer hour, boolean fal) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime now = LocalDateTime.parse(beginDate, formatter);
String date;
LocalDateTime oneHourLater;
if (fal) {
oneHourLater = now.plusHours((long)hour);
date = oneHourLater.format(formatter);
} else {
oneHourLater = now.minus(Duration.ofHours((long)hour));
date = oneHourLater.format(formatter);
}
return date;
}
public static long countDay(String begin, String end) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
long day = 0L;
try {
Date beginDate = format.parse(begin);
Date endDate = format.parse(end);
day = (endDate.getTime() - beginDate.getTime()) / 86400000L;
} catch (ParseException var8) {
var8.printStackTrace();
}
return day;
}
public static long countHour(String begin, String end) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
long hour = 0L;
try {
Date beginDate = format.parse(begin);
Date endDate = format.parse(end);
hour = (endDate.getTime() - beginDate.getTime()) / 3600000L;
} catch (ParseException var8) {
var8.printStackTrace();
}
return hour;
}
public static int[] splitYMD(String date) {
date = date.replace("-", "").replace(" ", "");
int[] ymd = new int[]{Integer.parseInt(date.substring(0, 4)), Integer.parseInt(date.substring(4, 6)), Integer.parseInt(date.substring(6, 8))};
return ymd;
}
public static int[] splitYMDH(String date) {
date = date.replace("-", "").replace(" ", "");
int[] ymd = new int[]{Integer.parseInt(date.substring(0, 4)), Integer.parseInt(date.substring(4, 6)), Integer.parseInt(date.substring(6, 8)), Integer.parseInt(date.substring(8, 10))};
return ymd;
}
private static int[] addOneDay(int year, int month, int day) {
if (isLeapYear(year)) {
++day;
if (day > DAYS_P_MONTH_LY[month - 1]) {
++month;
if (month > 12) {
++year;
month = 1;
}
day = 1;
}
} else {
++day;
if (day > DAYS_P_MONTH_CY[month - 1]) {
++month;
if (month > 12) {
++year;
month = 1;
}
day = 1;
}
}
int[] ymd = new int[]{year, month, day};
return ymd;
}
public static boolean isLeapYear(int year) {
return year >= gregorianCutoverYear ? year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) : year % 4 == 0;
}
public static String formatYear(int decimal) {
DecimalFormat df = new DecimalFormat("0000");
return df.format((long)decimal);
}
public static String formatMonthDay(int decimal) {
DecimalFormat df = new DecimalFormat("00");
return df.format((long)decimal);
}
public static int convert0to24(int hour) {
return hour == 0 ? 24 : hour;
}
}
更多推荐


所有评论(0)