计算两个日期之间的工作日数 [英] Calculate number of business days between two dates
问题描述
我需要计算两个给定日期之间的工作日数
我将假期列表作为用户提供的数组列表.
因此,我可以调查日期之间的每一天,并检查它的工作日,而不是像我下面提供的代码那样的联邦假日(工作正常)
I have requirement to calculate number of business days between two given dates
I have the list of holidays as an Array list provided by the user.
So I can investigate each and every day between the dates and check if its weekday and not federal holiday like the code I provided below (which is working fine)
但这非常昂贵,可以说是12个联邦假日,每天我都必须检查它而不是周末,
因此,如果我需要在5年之间进行计数,则需要365 * 5 * 12的21,000次迭代!太疯狂了(甚至不包括工作日的计算)
有更好的方法吗?
But this is very expensive, lets say 12 federal holidays and each day I will have to check its not a weekend,
so if I need to count between 5 years it will take 365 * 5 * 12 its 21,000 iterations! its crazy (not even including the calculation for business day)
Is there a better way?
package test;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.time.DateUtils;
public class TestDiff {
public static void main(String[] args) throws ParseException {
DateFormat formatter = new SimpleDateFormat("MM/dd/yy");
// add 4 years as an example
Date fromDate = formatter.parse("11/06/2017"),toDate = formatter.parse("11/29/2017");// DateUtils.addDays(fromDate,365 * 4);
int numberOfDaysCount=0;
int daysBetween = daysBetween(fromDate,toDate);
Date caurDate = fromDate;
for(int i=0;i<=daysBetween ; i++ ) {
if(isWeekDay(caurDate) && !isFederalHoliday(caurDate) )
numberOfDaysCount++;
caurDate = DateUtils.addDays(caurDate,1); // add one day
}
System.out.println("number of business days between "+fromDate+" and "+toDate+" is: "+numberOfDaysCount);
}
private static boolean isWeekDay(Date caurDate) {
Calendar c = Calendar.getInstance();
c.setTime(caurDate);
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
return dayOfWeek!= Calendar.SATURDAY && dayOfWeek!= Calendar.SUNDAY ;
}
private static boolean isFederalHoliday(Date caurDate) throws ParseException {
DateFormat formatter = new SimpleDateFormat("MM/dd/yy"); //list will come from dao.getFederalHoliday();
List<Date> federalHolidays = Arrays.asList(formatter.parse("01/02/2017"),formatter.parse("01/16/2017"),formatter.parse("02/20/2017"),formatter.parse("05/29/2017"),formatter.parse("07/04/2017"),formatter.parse("09/04/2017"),formatter.parse("10/09/2017"),formatter.parse("07/04/2017"),formatter.parse("11/10/2017"),formatter.parse("11/23/2017"),formatter.parse("12/25/2017"));
for (Date holiday : federalHolidays) {
if(DateUtils.isSameDay(caurDate,holiday)) //using Apache commons-lang
return true;
}
return false;
}
public static int daysBetween(Date d1, Date d2){
return (int)( (d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24));
}
}
推荐答案
这是Java 8中使用 java.time.*
.
Here's an answer implemented in Java 8 using java.time.*
.
public class TestSo47314277 {
/**
* A set of federal holidays. Compared to iteration, using a
* hash-based container provides a faster access for reading
* element via hash code. Using {@link Set} avoids duplicates.
* <p>
* Add more dates if needed.
*/
private static final Set<LocalDate> HOLIDAYS;
static {
List<LocalDate> dates = Arrays.asList(
LocalDate.of(2017, 1, 2),
LocalDate.of(2017, 1, 16),
LocalDate.of(2017, 2, 20),
LocalDate.of(2017, 5, 29),
LocalDate.of(2017, 7, 4),
LocalDate.of(2017, 9, 4),
LocalDate.of(2017, 10, 9),
LocalDate.of(2017, 11, 10),
LocalDate.of(2017, 11, 23),
LocalDate.of(2017, 12, 25)
);
HOLIDAYS = Collections.unmodifiableSet(new HashSet<>(dates));
}
public int getBusinessDays(LocalDate startInclusive, LocalDate endExclusive) {
if (startInclusive.isAfter(endExclusive)) {
String msg = "Start date " + startInclusive
+ " must be earlier than end date " + endExclusive;
throw new IllegalArgumentException(msg);
}
int businessDays = 0;
LocalDate d = startInclusive;
while (d.isBefore(endExclusive)) {
DayOfWeek dw = d.getDayOfWeek();
if (!HOLIDAYS.contains(d)
&& dw != DayOfWeek.SATURDAY
&& dw != DayOfWeek.SUNDAY) {
businessDays++;
}
d = d.plusDays(1);
}
return businessDays;
}
}
这篇关于计算两个日期之间的工作日数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!