将营业时间添加到Java DateTime

时间:2011-09-18 15:49:40

标签: java algorithm date

对于问题跟踪系统,我需要计算请求的响应时间。响应时间的计时器应仅在工作时间运行。我应该使用什么算法/库来完成这项任务? (当然,我知道Joda-Time或ObjectLab Kit,但找不到任何帮助我的任务。我错过了什么吗?)

示例:

  • 营业时间:上午9点至下午5点(每天8小时)
  • 最长响应时间:16小时

该方法可能类似于:

DateTime calculateResponseTime(DateTime issueReportedAt)

我将提供一些可能的输入和结果作为示例:

  • 星期一,2011-09-19,下午1:00 - >星期三,2011-09-21,下午1:00
  • 星期一,2011-09-19,6:05 pm - >星期四,2011-09-22,上午9:00
  • 星期五,2011-09-23,下午2:00 - >星期二,2011-09-27,下午2:00

4 个答案:

答案 0 :(得分:2)

您可以查看jBPM business calendar

另一个library允许您配置银行假期,但它没有营业时间的概念。

答案 1 :(得分:2)

我认为Oleg的建议正在考虑jBPM实现此功能的方式,以便为您自己的解决方案编码提供灵感。以下是我通过做Google Code Search从我找到的来源中大量借用的答案。

它没有考虑到假期,但我将把它作为锻炼给你。我可以建议使用web service每年更新限制日期列表吗?祝你好运!

    int fromHour = 9;
int fromMinute = 0;
int toHour = 17;
int toMinute = 0;
long maxResponseTime = 16;

Date calculateResponseTime(Date issueReportedAt, long responseHours) {

    Date end = null;

    Calendar responseTime = Calendar.getInstance();
    responseTime.setTime(issueReportedAt);

    int hourOfDay = responseTime.get(Calendar.HOUR_OF_DAY);
    int dayOfWeek = responseTime.get(Calendar.DAY_OF_WEEK);

    if (hourOfDay < fromHour) {
        responseTime.set(Calendar.HOUR, fromHour);

    }

    if (hourOfDay >= toHour || dayOfWeek == 1) {
        responseTime.add(Calendar.DATE, 1);
        responseTime.set(Calendar.HOUR_OF_DAY, fromHour);
        responseTime.set(Calendar.MINUTE, fromMinute);

    } else if (dayOfWeek == 7) {
        responseTime.add(Calendar.DATE, 2);
        responseTime.set(Calendar.HOUR_OF_DAY, fromHour);
        responseTime.set(Calendar.MINUTE, fromMinute);

    }

    int hour = responseTime.get(Calendar.HOUR_OF_DAY);
    int minute = responseTime.get(Calendar.MINUTE);

    long dateMilliseconds = ((hour * 60) + minute) * 60 * 1000;
    long dayPartEndMilleseconds = ((toHour * 60) + toMinute) * 60 * 1000;
    long millisecondsInThisDayPart = dayPartEndMilleseconds
            - dateMilliseconds;

    long durationMilliseconds = responseHours * 60 * 60 * 1000;

    if (durationMilliseconds < millisecondsInThisDayPart) {
        end = new Date(responseTime.getTimeInMillis()
                + durationMilliseconds);
    } else {
        long remainder = (durationMilliseconds - millisecondsInThisDayPart) / 60 / 60 / 1000;
        Date dayPartEndDate = new Date(responseTime.getTimeInMillis()
                + durationMilliseconds);

        responseTime.setTime(dayPartEndDate);

        end = calculateResponseTime(responseTime.getTime(), remainder);
    }

    return end;

}

@Test
public void testCalculateResponseTime() {

    Calendar issueReportedAt = Calendar.getInstance();
    Calendar expectedResponseTime = Calendar.getInstance();

    issueReportedAt.set(2011, 8, 19, 13, 0, 0);
    expectedResponseTime.set(2011, 8, 21, 13, 0, 0);

    assertTrue(expectedResponseTime.getTime().equals(
            calculateResponseTime(issueReportedAt.getTime(),
                    maxResponseTime)));

    issueReportedAt.set(2011, 8, 19, 18, 5, 0);
    expectedResponseTime.set(2011, 8, 22, 9, 0, 0);

    assertTrue(expectedResponseTime.getTime().equals(
            calculateResponseTime(issueReportedAt.getTime(),
                    maxResponseTime)));

    issueReportedAt.set(2011, 8, 23, 14, 0, 0);
    expectedResponseTime.set(2011, 8, 27, 14, 0, 0);

    assertTrue(expectedResponseTime.getTime().equals(
            calculateResponseTime(issueReportedAt.getTime(),
                    maxResponseTime)));

}

答案 2 :(得分:0)

你需要在Anils回答的标准化部分添加一个额外的if情况,因为如果问题是在星期五上午10:00报告并且responseHours是10,那么在下一次递归调用中,issueReportedAt将是星期五晚上10点,女巫将被标准化为星期六晚上9点,女巫也是无效的。

if (hourOfDay >= WorkingHours.TO_HOUR && dayOfWeek == Calendar.FRIDAY) {
        responseTime.add(Calendar.DATE, 3);
        responseTime.set(Calendar.HOUR_OF_DAY, WorkingHours.FROM_HOUR);
        responseTime.set(Calendar.MINUTE, WorkingHours.FROM_MINUTE);
}

答案 3 :(得分:0)

下面的代码确实解决了这个问题

IDlist = df_original.ID.tolist()
Countlist = df_original.Count.tolist()
...