将营业时间添加到 Java DateTime

发布于 2024-12-04 23:20:38 字数 542 浏览 0 评论 0原文

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

示例:

  • 工作时间:上午 9 点 - 下午 5 点(每天 8 小时)
  • 最大响应时间:16 我

该方法可能看起来像:

DateTime calculateResponseTime(DateTime issueReportedAt)

将给出一些可能的输入和结果,例如:

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

For an issue tracking system I need to calculate the response time for a request. The timer for response time should only be running during business hours. What algorithm/library should I use for this task? (Sure thing, I know about Joda-Time or ObjectLab Kit, but couldn't find anything helping with my task. Am I missing something?)

Example:

  • Business hours: 9am - 5pm (8 hours per day)
  • Maximum response time: 16 hours

The method may look something like:

DateTime calculateResponseTime(DateTime issueReportedAt)

I'll give some possible inputs and results as example:

  • Mon, 2011-09-19, 1:00pm -> Wed, 2011-09-21, 1:00pm
  • Mon, 2011-09-19, 6:05pm -> Thu, 2011-09-22, 9:00am
  • Fri, 2011-09-23, 2:00pm -> Tue, 2011-09-27, 2:00pm

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

软甜啾 2024-12-11 23:20:38

您可以查看jBPM 业务日历

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

You may take a look on the jBPM business calendar.

Another library allows you configure bank holidays but it doesn't have a notion of business hours.

淡忘如思 2024-12-11 23:20:38

我认为 Oleg 的建议是看看 jBPM 实现此功能的方式,以获取编写自己的解决方案的灵感。下面是我的答案,大量借用了我通过执行 Google 代码搜索

它不考虑假期,但我会把它留给你作为练习。我可以建议使用网络服务每年更新限制日期列表?祝你好运!

    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)));

}

I think what Oleg was suggesting was taking a look at the way jBPM implements this functionality for inspiration for coding your own solution. Below is my answer borrowing heavily from the source I found by doing a Google Code Search.

It does not take into account holidays, but I will leave that as an exercise for you. May I suggest using a web service to annually update a restricted date list? Good luck!

    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)));

}
黑寡妇 2024-12-11 23:20:38

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

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);
}

You need to add an extra if case to the normalization part from Anils answer because if the issue is reported on a Friday 10:00 AM and the responseHours is 10, than in the next recursive call the issueReportedAt will be Friday 10 PM, witch will be normalized to Saturday 9:00 PM, witch is invalid as well.

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);
}
狼性发作 2024-12-11 23:20:38

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

public static Date addBusinessHours(Calendar startDate, int hours, int workingHourStart, int workingHourEnd){
    System.out.println("Entering: Date Time " + startDate.getTime() + " | Remaining Hours: "+ hours + " | Working hours ("+workingHourStart+"-"+workingHourEnd+")");

    if(hours == 0){
        return startDate.getTime();
    }
    int hourOfDay = startDate.get(Calendar.HOUR_OF_DAY);
    if(startDate.get(Calendar.MINUTE) > 0){
        hourOfDay = hourOfDay +1;
    }

    int dayOfWeek = startDate.get(Calendar.DAY_OF_WEEK);

    if(dayOfWeek == Calendar.SATURDAY){
        startDate.add(Calendar.DATE, 2);
        startDate.set(Calendar.HOUR_OF_DAY, workingHourStart);
        startDate.set(Calendar.MINUTE, 0);
        startDate.set(Calendar.SECOND, 0);
        addBusinessHours(startDate, hours, workingHourStart, workingHourEnd);
    }
    if(dayOfWeek == Calendar.SUNDAY){
        startDate.add(Calendar.DATE, 1);
        startDate.set(Calendar.HOUR_OF_DAY, workingHourStart);
        startDate.set(Calendar.MINUTE, 0);
        startDate.set(Calendar.SECOND, 0);
        addBusinessHours(startDate, hours, workingHourStart, workingHourEnd);
    }

    if(dayOfWeek != Calendar.SATURDAY && dayOfWeek != Calendar.SUNDAY){
        if(hourOfDay < workingHourStart){
            startDate.set(Calendar.HOUR_OF_DAY, workingHourStart);
            startDate.set(Calendar.MINUTE, 0);
            startDate.set(Calendar.SECOND, 0);
            hourOfDay = startDate.get(Calendar.HOUR_OF_DAY);
            dayOfWeek = startDate.get(Calendar.DAY_OF_WEEK);
            addBusinessHours(startDate, hours, workingHourStart, workingHourEnd);
        }
        else if(hourOfDay >= workingHourEnd){

            startDate.add(Calendar.DATE, 1);
            startDate.set(Calendar.HOUR_OF_DAY, workingHourStart);
            startDate.set(Calendar.MINUTE, 0);
            startDate.set(Calendar.SECOND, 0);
            hourOfDay = startDate.get(Calendar.HOUR_OF_DAY);
            dayOfWeek = startDate.get(Calendar.DAY_OF_WEEK);
            addBusinessHours(startDate, hours, workingHourStart, workingHourEnd);
        }

        else if(hourOfDay >= workingHourStart && hourOfDay < workingHourEnd){
            if(hours+hourOfDay <= workingHourEnd){
                startDate.add(Calendar.HOUR_OF_DAY, hours);
                return startDate.getTime();
            }else{
                //System.out.println("¤¤" + startDate.getTime() );
                startDate.add(Calendar.DATE, 1);
                //System.out.println("¤¤" + startDate.getTime() );
                startDate.set(Calendar.HOUR_OF_DAY, workingHourStart);
                startDate.set(Calendar.MINUTE, 0);
                startDate.set(Calendar.SECOND, 0);
                //System.out.println("¤¤" + startDate.getTime() );

                System.out.println("##"+hours+ "##"+ workingHourEnd + "##" + hourOfDay);
                int remaining_hours = hours - (workingHourEnd - hourOfDay);
                addBusinessHours(startDate, remaining_hours, workingHourStart, workingHourEnd);
            }
        }
    }

    return startDate.getTime();
}

Below code does solve the this problem

public static Date addBusinessHours(Calendar startDate, int hours, int workingHourStart, int workingHourEnd){
    System.out.println("Entering: Date Time " + startDate.getTime() + " | Remaining Hours: "+ hours + " | Working hours ("+workingHourStart+"-"+workingHourEnd+")");

    if(hours == 0){
        return startDate.getTime();
    }
    int hourOfDay = startDate.get(Calendar.HOUR_OF_DAY);
    if(startDate.get(Calendar.MINUTE) > 0){
        hourOfDay = hourOfDay +1;
    }

    int dayOfWeek = startDate.get(Calendar.DAY_OF_WEEK);

    if(dayOfWeek == Calendar.SATURDAY){
        startDate.add(Calendar.DATE, 2);
        startDate.set(Calendar.HOUR_OF_DAY, workingHourStart);
        startDate.set(Calendar.MINUTE, 0);
        startDate.set(Calendar.SECOND, 0);
        addBusinessHours(startDate, hours, workingHourStart, workingHourEnd);
    }
    if(dayOfWeek == Calendar.SUNDAY){
        startDate.add(Calendar.DATE, 1);
        startDate.set(Calendar.HOUR_OF_DAY, workingHourStart);
        startDate.set(Calendar.MINUTE, 0);
        startDate.set(Calendar.SECOND, 0);
        addBusinessHours(startDate, hours, workingHourStart, workingHourEnd);
    }

    if(dayOfWeek != Calendar.SATURDAY && dayOfWeek != Calendar.SUNDAY){
        if(hourOfDay < workingHourStart){
            startDate.set(Calendar.HOUR_OF_DAY, workingHourStart);
            startDate.set(Calendar.MINUTE, 0);
            startDate.set(Calendar.SECOND, 0);
            hourOfDay = startDate.get(Calendar.HOUR_OF_DAY);
            dayOfWeek = startDate.get(Calendar.DAY_OF_WEEK);
            addBusinessHours(startDate, hours, workingHourStart, workingHourEnd);
        }
        else if(hourOfDay >= workingHourEnd){

            startDate.add(Calendar.DATE, 1);
            startDate.set(Calendar.HOUR_OF_DAY, workingHourStart);
            startDate.set(Calendar.MINUTE, 0);
            startDate.set(Calendar.SECOND, 0);
            hourOfDay = startDate.get(Calendar.HOUR_OF_DAY);
            dayOfWeek = startDate.get(Calendar.DAY_OF_WEEK);
            addBusinessHours(startDate, hours, workingHourStart, workingHourEnd);
        }

        else if(hourOfDay >= workingHourStart && hourOfDay < workingHourEnd){
            if(hours+hourOfDay <= workingHourEnd){
                startDate.add(Calendar.HOUR_OF_DAY, hours);
                return startDate.getTime();
            }else{
                //System.out.println("¤¤" + startDate.getTime() );
                startDate.add(Calendar.DATE, 1);
                //System.out.println("¤¤" + startDate.getTime() );
                startDate.set(Calendar.HOUR_OF_DAY, workingHourStart);
                startDate.set(Calendar.MINUTE, 0);
                startDate.set(Calendar.SECOND, 0);
                //System.out.println("¤¤" + startDate.getTime() );

                System.out.println("##"+hours+ "##"+ workingHourEnd + "##" + hourOfDay);
                int remaining_hours = hours - (workingHourEnd - hourOfDay);
                addBusinessHours(startDate, remaining_hours, workingHourStart, workingHourEnd);
            }
        }
    }

    return startDate.getTime();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文