下面我有3种方法。第一个很简单。它只计算总天数。但是,第二个不仅会计算天数,还会忽略传递给方法的星期几。
我的问题是第三种方法并不总是正确的。它应该匹配第二种方法。我猜它与闰年有关,因为当它不正确时差异通常为+ = 3 | 4。
我试图以某种方式模仿Excel weekday(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,2,4,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 LocalDate end, 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, 9, 7);
final LocalDate end = LocalDate.of(2025, 6, 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, end, 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 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 LocalDate end, 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;
}
}
答案 0 :(得分:10)
如果我们谈论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();
}
答案 1 :(得分:4)
您使用的是错误的Excel公式。请参阅&#34;使用SUM和INT功能来计算工作日数&#34;您提供的网站。它将公式表述为:
=SUM(INT((WEEKDAY(A2-{2,3,4,5,6})+B2-A2)/7))
在Excel中,星期日是1,星期六是7.花括号内的数字表示要包括的星期几。因此,对于您的情况,公式将是:
=SUM(INT((WEEKDAY(A2-{2,3,5,7})+B2-A2)/7))
请参阅随附的屏幕截图:
以下代码返回时返回2247:
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
public class SO25798876 {
public static void main(String[] args) {
String strStartDate = "09/07/2014";
String strEndDate = "06/13/2025";
String pattern = "MM/dd/yyyy";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
LocalDate startDate = LocalDate.parse(strStartDate, formatter);
LocalDate endDate = LocalDate.parse(strEndDate, formatter);
int count = 0;
while(startDate.isBefore(endDate) || startDate.isEqual(endDate)) { // you may want to not to use the isEqual method
DayOfWeek dayOfWeek = startDate.getDayOfWeek();
if(!(dayOfWeek == DayOfWeek.SUNDAY || dayOfWeek == DayOfWeek.WEDNESDAY || dayOfWeek == DayOfWeek.FRIDAY)) {
count++;
}
startDate = startDate.plusDays(1);
}
System.out.println(count);
}
}
如果添加以下代码,您还提到了java.time
可能没有考虑闰年的疑问,这是错误的
long year = startDate.getYear();
if(Year.isLeap(year)) {
Month month = startDate.getMonth();
if(month == Month.FEBRUARY && startDate.getDayOfMonth() == 29) {
System.out.println("Calculated 29th Feb for the year: " + year);
}
}
你会看到它正在打印:
Calculated 29th Feb for the year: 2016
Calculated 29th Feb for the year: 2020
Calculated 29th Feb for the year: 2024
最后,计数将为2247
,与Excel结果相符。
快乐的编码。
-Tapas