寻找下一个工作日

6

假设我已经在我的数据库中存储了一堆假日。

我需要做的是找出下一个工作日,不包括星期六和数据库中定义的公共假期。

例如:

假设今天是2月15日星期五,17日和18日是作为日期时间在数据库中定义的公共假期。现在当我按下一个名为“下一个工作日”的按钮时,它应该返回2月19日。

最有效的方法是什么?


我不明白为什么在这种情况下你想要找到下一个工作日... 我相信你不会告诉你的员工 XYZ 是你的下一个工作日... 只是问一下... 如果有原因,能否请分享? - Fahim Parkar
这很大程度上取决于您的数据库布局。顺便说一句,我认为这个问题与SQL更相关,而不是Java。 - Marcelo
@Sapan:为什么在这里标记eclipse-rcp?你能解释一下吗? - Fahim Parkar
1
@FahimParkar - 一些公司有“在2个工作日内回复客户”的政策。这种功能会很有用。 - Hans Kesting
哦,好的汉斯..我懂了 :)我以为你已经添加了,因为我看到你的名字在编辑中...之前没有出现过...如果你没有添加,那就没事了... - Fahim Parkar
显示剩余2条评论
4个回答

12

最简单的方法。

步骤1:从数据库中获取假期并将其格式化为您的格式,将其保存在一个List<String>中。

步骤2:创建一个添加日期的方法。

public static Date addDays(Date d, int days) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(d);
    cal.add(Calendar.DATE, days);
    return cal.getTime();
}
第三步:创建一个查找假日的方法。
public boolean isBankHoliday(java.util.Date d) {
    Calendar c = new GregorianCalendar();
    c.setTime(d);
    if((Calendar.SATURDAY == c.get(c.DAY_OF_WEEK)) || (Calendar.SUNDAY == c.get(c.DAY_OF_WEEK)) || bankHolidays.contains(dString)) {
        return (true);
    } else {
        return false;
    }
} 

步骤4:获取您的输入日期。检查银行假期,循环直至找到一个工作日。

while (isBankHoliday(myDate)) {
    myDate = addDays(myDate, 1);
}

dString被声明在哪里? - JustinKSU
@vaandu,第4步应该是while(isBankHoliday(myDate)),而不是while(!isBankHoliday(myDate))(这里不应该有"!"),因为你想要找到下一个工作日,而不是下一个假日。 - Robert P

3
您可以使用DateCalculatorJoda(可选)来实现此目的。在下面的示例中,假日存储在一个Set集合中,并使用moveByBusinessDays方法。
import java.util.HashSet;

import junit.framework.Assert;

import net.objectlab.kit.datecalc.common.DateCalculator;
import net.objectlab.kit.datecalc.common.DefaultHolidayCalendar;
import net.objectlab.kit.datecalc.common.HolidayHandlerType;
import net.objectlab.kit.datecalc.joda.LocalDateKitCalculatorsFactory;

import org.joda.time.LocalDate;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;

public class NextBusinessDayTest {

    private DateCalculator<LocalDate> dateCalculator;
    private final LocalDate startDate = new LocalDate(2012, 2, 9); // Thursday


    @BeforeSuite
    public void setUp() {
        HashSet<LocalDate> holidays = new HashSet<LocalDate>();
        holidays.add(new LocalDate(2012, 2, 10));  // Friday
        holidays.add(new LocalDate(2012, 2, 14));  // Tuesday

        DefaultHolidayCalendar<LocalDate> holidayCalendar = new DefaultHolidayCalendar<LocalDate>(holidays);

        LocalDateKitCalculatorsFactory.getDefaultInstance().registerHolidays("holidays", holidayCalendar);
        dateCalculator = LocalDateKitCalculatorsFactory.getDefaultInstance().getDateCalculator("holidays", HolidayHandlerType.FORWARD);
    }


    @Test
    public void testNextBusinessDay() {
        dateCalculator.setStartDate(startDate);
        Assert.assertEquals(dateCalculator.moveByBusinessDays(1).getCurrentBusinessDate(),
        new LocalDate(2012, 2, 13)); // skips the 10th (holiday), 11th and 12th (weekend)

        dateCalculator.setStartDate(startDate);
        Assert.assertEquals(dateCalculator.moveByBusinessDays(2).getCurrentBusinessDate(),
        new LocalDate(2012, 2, 15)); // also skips the 14th (holiday)
    }
}

编辑:

  1. 有一种不需要Joda的日期计算库的替代版本。
  2. 检查一下这个库是否提供了其他在你的应用中会有用的功能。如果寻找下一个工作日是唯一的使用案例,那么自己编写方法会是更好的选择。Vanathi已经很好地描述了基本方法。

3

仅提供一个纯SQL解决方案:

DECLARE @InDate DATETIME
SET @InDate = '25/12/2011'

;WITH CTE ([Date]) AS
(   SELECT  DATEADD(DAY, 1, CAST(@InDate AS DATE)) [Date]
    UNION ALL
    SELECT  DATEADD(DAY, 1, [Date])
    FROM    CTE
    WHERE   [Date] IN (SELECT [Date] FROM YourHolidayTable)
    OR      DATENAME(WEEKDAY, [Date]) IN ('Saturday', 'Sunday')
)

SELECT  MAX([Date]) [NextWorkingDay]
FROM    CTE

0

我不知道Java中是否有内置函数可以做到这一点,但如果没有:

从我的经验来看 -

最简单的方法可能是存储哪些日期是周末以及公共假期? 或者如果您有一个参考点(比如2012年1月1日),那么您可以存储它是一周的哪一天,然后在计算新值时使用模7算术?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接