Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add business hours to Java DateTime

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
like image 540
Chris Avatar asked Sep 18 '11 15:09

Chris


People also ask

How do you add HH mm in Java?

SimpleDateFormat sdf = new SimpleDateFormat("dd:HH:mm:ss"); Date d0 = sdf. parse("00:00:00:00"); // ref Date d1 = sdf. parse("00:01:09:14"); Date d2 = sdf.

What is the use of calendar getInstance () in Java?

The getInstance() method in Calendar class is used to get a calendar using the current time zone and locale of the system. Parameters: The method does not take any parameters. Return Value: The method returns the calendar.

What is Java toInstant?

The toInstant() method of Date class in Java is used to convert a Date object to an Instant object. An Instant is created during the conversion which is used to represent the same point on the timeline as this Date.


2 Answers

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.

like image 71
Oleg Pavliv Avatar answered Oct 21 '22 13:10

Oleg Pavliv


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

}
like image 21
Anil U Avatar answered Oct 21 '22 12:10

Anil U