下面我有3种方法.第一个很简单.它只计算总天数.但是,第二个不仅会计算天数,还会忽略传递给方法的星期几.
我的问题是第三种方法并不总是正确的.它应该匹配第二种方法.我猜它与闰年有关,因为当它不正确时,差异通常是= 3 | 4.
附加信息
我试图以某种方式模拟Excel的工作日(serial_number,[return_type])公式.
serial_number = startDate:Date - daysOfWeekToInclude:Array<Integer>
例
| A | B | C +---------+----------------------------------------------------+----------- 1 | Start | =DATE(2014,9,7) | 9/7/2014 2 | End | =DATE(2025,6,13) | 6/13/2025 3 | Include | ={1,2,4,6} (Mon,Tue,Thu,& Sat) | <Disp Only> 4 | Days | =SUM(INT((WEEKDAY($B$1-{1,6},1)+$B$2-$B$1)/7)) | 2248
这里有关于此功能的更多信息:How to count / calculate the number of days between two dates in Excel?
原始图像
>只需计算两个日期之间的天数.
public static int simpleDaysBetween(final LocalDate start,final LocalDate end) { return (int) ChronoUnit.DAYS.between(start,end); }
>使用循环计算天数,忽略一周中的某些天.
public static int betterDaysBetween(final LocalDate start,final LocalDate end,final List<DayOfWeek> ignore) { int count = 0; LocalDate curr = start.plusDays(0); while (curr.isBefore(end)) { if (!ignore.contains(curr.getDayOfWeek())) { count++; } curr = curr.plusDays(1); // Increment by a day. } return count; }
>计算天数.再次,但没有循环.
public static int bestDaysBetween(final LocalDate start,final List<DayOfWeek> ignore) { int days = simpleDaysBetween(start,end); if (days == 0) { return 0; } if (!ignore.isEmpty()) { int weeks = days / 7; int startDay = start.getDayOfWeek().getValue(); int endDay = end.getDayOfWeek().getValue(); int diff = weeks * ignore.size(); for (DayOfWeek day : ignore) { int currDay = day.getValue(); if (startDay <= currDay) { diff++; } if (endDay > currDay) { diff++; } } if (endDay > startDay) { diff -= endDay - startDay; } return days - diff; } return days; }
完整代码
import java.time.DayOfWeek; import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.List; public class DayCounter { public static void main(String[] args) { final LocalDate start = LocalDate.of(2014,7); final LocalDate end = LocalDate.of(2025,13); List<DayOfWeek> ignore = Arrays.asList(DayOfWeek.SUNDAY,DayOfWeek.WEDNESDAY,DayOfWeek.FRIDAY); print(start); print(end); System.out.println(simpleDaysBetween(start,end)); System.out.println(betterDaysBetween(start,end,ignore)); System.out.println(bestDaysBetween(start,ignore)); } public static void print(LocalDate date) { System.out.printf("%s -> %s%n",date,date.getDayOfWeek()); } public static int simpleDaysBetween(final LocalDate start,final LocalDate end) { return (int) ChronoUnit.DAYS.between(start,end); } public static int betterDaysBetween(final LocalDate start,final List<DayOfWeek> ignore) { int count = 0; LocalDate curr = start.plusDays(0); while (curr.isBefore(end)) { if (!ignore.contains(curr.getDayOfWeek())) { count++; } curr = curr.plusDays(1); // Increment by a day. } return count; } public static int bestDaysBetween(final LocalDate start,final List<DayOfWeek> ignore) { int days = simpleDaysBetween(start,end); if (days == 0) { return 0; } if (!ignore.isEmpty()) { int weeks = days / 7; int startDay = start.getDayOfWeek().getValue(); int endDay = end.getDayOfWeek().getValue(); int diff = weeks * ignore.size(); for (DayOfWeek day : ignore) { int currDay = day.getValue(); if (startDay <= currDay) { diff++; } if (endDay > currDay) { diff++; } } if (endDay > startDay) { diff -= endDay - startDay; } return days - diff; } return days; } }
解决方法
如果我们谈论Java 8 API,为什么不使用Java 8功能…
static long daysBetween(LocalDate start,LocalDate end,List<DayOfWeek> ignore) { return Stream.iterate(start,d->d.plusDays(1)) .limit(start.until(end,ChronoUnit.DAYS)) .filter(d->!ignore.contains(d.getDayOfWeek())) .count(); }