Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将工作时间添加到Java DateTime_Java_Algorithm_Date - Fatal编程技术网

将工作时间添加到Java DateTime

将工作时间添加到Java DateTime,java,algorithm,date,Java,Algorithm,Date,对于问题跟踪系统,我需要计算请求的响应时间。响应时间计时器应仅在工作时间内运行。此任务应使用什么算法/库?(当然,我知道Joda Time或ObjectLab Kit,但找不到任何有助于我完成任务的东西。我是否遗漏了什么?) 例如: 营业时间:上午9时至下午5时(每天8小时) 最长响应时间:16小时 该方法可能类似于: DateTime calculateResponseTime(DateTime issueReportedAt) 我将给出一些可能的输入和结果作为示例: 2011年9月1

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

例如:

  • 营业时间:上午9时至下午5时(每天8小时)
  • 最长响应时间:16小时
该方法可能类似于:

DateTime calculateResponseTime(DateTime issueReportedAt)
我将给出一些可能的输入和结果作为示例:

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

您可以在屏幕上查看


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

我认为Oleg的建议是查看jBPM实现此功能的方式,以获得编写您自己的解决方案的灵感。下面是我的答案,大量借用了我通过做一个调查发现的来源

它没有考虑到假期,但我会留给你作为练习。我是否可以建议每年使用一次更新限制日期列表?祝你好运

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

}
int fromHour=9;
int frommin=0;
整小时=17;
int-toMinute=0;
长最大响应时间=16;
日期计算响应时间(日期发布报告,长响应小时){
日期结束=空;
Calendar responseTime=Calendar.getInstance();
响应时间设置时间(发布报告数据);
int hourOfDay=responseTime.get(日历小时);
int dayOfWeek=responseTime.get(Calendar.dayOfWeek);
如果(小时日<小时){
responseTime.set(Calendar.HOUR,fromHour);
}
如果(hourOfDay>=toHour | | dayOfWeek==1){
responseTime.add(Calendar.DATE,1);
responseTime.set(日历.HOUR,fromHour);
responseTime.set(Calendar.MINUTE,fromMinute);
}否则如果(星期五==7){
添加(Calendar.DATE,2);
responseTime.set(日历.HOUR,fromHour);
responseTime.set(Calendar.MINUTE,fromMinute);
}
int hour=responseTime.get(日历.hour,OF,OF,OF,DAY);
int minute=responseTime.get(Calendar.minute);
长日期毫秒=((小时*60)+分钟)*60*1000;
长DayPartEndMillesons=((toHour*60)+toMinute)*60*1000;
此DayPart中的长毫秒=DayPartEndMills
-日期毫秒;
长持续时间毫秒=响应小时数*60*60*1000;
if(持续时间毫秒<毫秒此日期部分){
end=新日期(responseTime.getTimeInMillis()
+持续时间(毫秒);
}否则{
长余数=(持续毫秒-毫秒在这一天的部分)/60/60/1000;
Date dayPartEndDate=新日期(responseTime.getTimeInMillis()
+持续时间(毫秒);
responseTime.setTime(dayPartEndDate);
end=calculateResponseTime(responseTime.getTime(),余数);
}
返回端;
}
@试验
public void testCalculateResponseTime(){
Calendar issueReportedAt=Calendar.getInstance();
Calendar expectedResponseTime=Calendar.getInstance();
发布报告数据集(2011,8,19,13,0,0);
expectedResponseTime.set(2011,8,21,13,0,0);
assertTrue(expectedResponseTime.getTime().equals(
calculateResponseTime(IssuereReportedat.getTime(),
最大响应时间);
发布报告数据集(2011,8,19,18,5,0);
expectedResponseTime.set(2011,8,22,9,0,0);
assertTrue(expectedResponseTime.getTime().equals(
calculateResponseTime(IssuereReportedat.getTime(),
最大响应时间);
发布报告数据集(2011,8,23,14,0,0);
expectedResponseTime.set(2011,8,27,14,0,0);
assertTrue(expectedResponseTime.getTime().equals(
calculateResponseTime(IssuereReportedat.getTime(),
最大响应时间);
}

您需要在Anils答案的规范化部分添加一个额外的if case,因为如果问题在星期五上午10:00报告,响应时间为10小时,那么在下一个递归调用中,IssuerReportedat将在星期五晚上10点,witch将规范化为星期六晚上9:00,witch也无效

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

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

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();
}
public static Date addBusinessHours(日历开始日期、整数小时、整数工作小时开始、整数工作小时结束){
System.out.println(“输入:日期时间”+startDate.getTime()+”|剩余小时数:“+Hours+”|工作小时数(“+workingHourStart+”-“+workinghourrend+”));
如果(小时==0){
返回startDate.getTime();
}
int hourOfDay=startDate.get(日历小时);
如果(开始日期获取(日历分钟)>0){
hourOfDay=hourOfDay+1;
}
int dayOfWeek=startDate.get(Calendar.DAY,OF WEEK);
如果(dayOfWeek==日历。星期六){
startDate.add(Calendar.DATE,2);
startDate.set(日历小时,工作小时开始);
开始日期设置(日历分钟,0);
开始日期设置(日历秒,0);
添加营业时间(开始日期、小时数、工作小时数开始、工作小时数);
}
if(dayOfWeek==日历。星期日){
startDate.add(Calendar.DATE,1);
startDate.set(日历小时,工作小时开始);
开始日期设置(日历分钟,0);
开始日期设置(日历秒,0);
添加营业时间(开始日期、小时数、工作小时数开始、工作小时数);
}
如果(dayOfWeek!=Calendar.SATURDAY&&dayOfWeek!=Calendar.SUNDAY){
if(小时天数<工作小时开始){
startDate.set(日历小时,工作小时开始);
开始日期设置(日历分钟,0);
开始日期设置(日历秒,0);
hourOfDay=startDate.get(日历小时);
dayOfWeek=startDate.get(校准