Java 根据多个 MM-dd 日期计算总时长(包含当日和次日)
下面我将介绍如何根据多个"MM-dd"格式的日期(可能跨年)来计算总时长,特别处理当日和次日的情况。
解决方案
方法思路
将输入的"MM-dd"格式转换为完整的日期(考虑跨年情况)
对日期进行排序
计算相邻日期之间的时间差
累加得到总时长
运行代码
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;public class DateDurationCalculator {// 主计算方法public static Duration calculateTotalDuration(List<String> monthDayStrings, LocalDate today) {if (monthDayStrings == null || monthDayStrings.isEmpty()) {return Duration.ZERO;}// 转换所有日期为LocalDate(处理跨年)List<LocalDate> dates = convertMonthDayToDates(monthDayStrings, today);// 对日期进行排序Collections.sort(dates);// 计算总时长Duration totalDuration = Duration.ZERO;for (int i = 0; i < dates.size() - 1; i++) {LocalDate start = dates.get(i);LocalDate end = dates.get(i + 1);// 计算两个日期之间的天数long daysBetween = ChronoUnit.DAYS.between(start, end);// 如果日期连续(当日和次日)if (daysBetween == 1) {totalDuration = totalDuration.plus(Duration.ofDays(1));} else {// 非连续日期,只计算单个日期totalDuration = totalDuration.plus(Duration.ofDays(1));}}// 加上最后一个日期return totalDuration.plus(Duration.ofDays(1));}// 将MM-dd转换为LocalDate,处理跨年情况private static List<LocalDate> convertMonthDayToDates(List<String> monthDayStrings, LocalDate today) {DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");List<LocalDate> dates = new ArrayList<>();for (String monthDay : monthDayStrings) {MonthDay md = MonthDay.parse(monthDay, formatter);// 获取可能的年份(今年或明年)LocalDate date = md.atYear(today.getYear());if (date.isBefore(today)) {// 如果日期已经过去,则认为是明年date = md.atYear(today.getYear() + 1);}dates.add(date);}return dates;}public static void main(String[] args) {// 示例使用LocalDate today = LocalDate.now();List<String> dates = Arrays.asList("12-25", "12-26", "01-01", "01-02");Duration duration = calculateTotalDuration(dates, today);System.out.println("总天数: " + duration.toDays());System.out.println("总小时数: " + duration.toHours());}
}
关键点说明
跨年处理:
使用
MonthDay
类解析"MM-dd"格式比较日期与当前日期,决定使用今年还是明年的年份
当日和次日判断:
使用
ChronoUnit.DAYS.between()
计算日期差差值为1表示是连续的当日和次日
总时长计算:
连续日期计算为完整时间段
非连续日期单独计算
输出结果:
可以获取总天数、小时数等不同单位的时长
// 测试跨年情况
List<String> testDates1 = Arrays.asList("12-30", "12-31", "01-01");
Duration result1 = calculateTotalDuration(testDates1, LocalDate.of(2023, 1, 1));
// 应返回3天(12-30, 12-31, 01-01)// 测试非连续日期
List<String> testDates2 = Arrays.asList("01-01", "01-03", "01-05");
Duration result2 = calculateTotalDuration(testDates2, LocalDate.of(2023, 1, 1));
// 应返回3天(每个日期单独计算)