需要帮助计算JAVA中的溢出时间

时间:2016-04-22 01:30:50

标签: java datetime

大家好日子!我急需你的帮助。我有一个要求,我必须计算任务的估计开始/结束时间。鉴于下图中的数字,我将如何在java中执行此操作?请注意我是Java的新手,所以请不要对此大喊:(

This is the desired Output I want :)

**This is what I've done so far based on master MadProgrammer**.

LocalTime openingTime = LocalTime.of(8, 0);
LocalTime closingTime = LocalTime.of(18, 0);
LocalDateTime jobStartAt = LocalDateTime.of(2012, 7, 31, 8, 0);
LocalDateTime closingAt = LocalDateTime.of(2012, 7, 31, 18, 0);
long minutesDuration = (long) 12*60;

System.out.println("start is " + printDateTime(jobStartAt));
jobStartAt = GetSpilledTime(openingTime, closingTime, closingAt, jobStartAt, minutesDuration);
System.out.println("end is " + printDateTime(jobStartAt)); 

private static LocalDateTime GetSpilledTime(LocalTime openingTime,
        LocalTime closingTime, LocalDateTime closingAt,
        LocalDateTime jobStartAt, long minutesDuration) {

    LocalDateTime estimatedEndTime = jobStartAt
            .plusMinutes(minutesDuration);

    if (estimatedEndTime.isAfter(closingAt)
            || estimatedEndTime.isEqual(closingAt)) {
        LocalDateTime fallOverStartAt = jobStartAt;
        do {
            Duration duration = Duration.between(closingAt,
                    estimatedEndTime);
            estimatedEndTime = LocalDateTime.of(
                    fallOverStartAt.toLocalDate(), closingTime);

            fallOverStartAt = fallOverStartAt.plusDays(1);
            fallOverStartAt = LocalDateTime.of(
                    fallOverStartAt.toLocalDate(), openingTime);
            estimatedEndTime = fallOverStartAt
                    .plusHours(duration.toHours());

            closingAt = closingAt.plusDays(1);
        } while (estimatedEndTime.isAfter(closingAt));

    } else {
        // Job will start on/at jobStartAt
        // and will end on/at estimatedEndTime
    }

    jobStartAt = estimatedEndTime;

    return jobStartAt;
}

1 个答案:

答案 0 :(得分:1)

首先熟悉Java 8的Time API,java.time框架。

你将在这里度过一段时间。

接下来,知道你有什么......

  • A"开始日期" (01/01/2017
  • A"开始营业"时间(08:00am
  • A"业务结束"时间(06:00pm
  • A"持续时间以小时为单位"每项任务

我们需要知道的是,当任务的预期结束时间超过业务结束时#34;时间和数量,这需要我们将剩余的时间添加到"业务开始"第二天,基本上重复这个过程,直到估计的结束时间在业务结束之前#34;时间

让我们从基本的"已知"开始信息...

LocalTime openingTime = LocalTime.of(8, 0);
LocalTime closingTime = LocalTime.of(18, 0);

LocalDate startAt = LocalDate.of(2017, Month.JANUARY, 1);

然后根据该信息,我们可以获取任务的持续时间并计算其估计的结束日期/时间

LocalDateTime estimatedEndTime = jobStartAt.plusHours(task.getDurationInHours());
if (estimatedEndTime.isAfter(closingAt) || estimatedEndTime.isEqual(closingAt)) {
    LocalDateTime fallOverStartAt = jobStartAt;
    do {
        Duration duration = Duration.between(closingAt, estimatedEndTime);
        estimatedEndTime = LocalDateTime.of(fallOverStartAt.toLocalDate(), closingTime);

        fallOverStartAt = fallOverStartAt.plusDays(1);
        fallOverStartAt = LocalDateTime.of(fallOverStartAt.toLocalDate(), openingTime);
        estimatedEndTime = fallOverStartAt.plusHours(duration.toHours());
        closingAt = closingAt.plusDays(1);
    } while (estimatedEndTime.isAfter(closingAt));
    // Job will start on/at jobStartAt
    // and will end on/at estimatedEndTime
} else {
    // Job will start on/at jobStartAt
    // and will end on/at estimatedEndTime
}

// The next job starts here
jobStartAt = estimatedEndTime;

好的,从概念上讲,所有这一切都是,从给定的时间点开始,增加了它的小时数。它会检查时间是否大于或等于业务结束时间,如果是,则循环,添加"溢出"从第二天开始营业,直至工作结束前工作结束。

然后,您将在jobStartAt中显示开始时间/日期,在estimatedEndTime中显示结束时间/日期。

estimatedEndTime然后成为下一个工作的开始日期/时间,你基本上会重复,直到你完成。

  

如果营业时间有多个条目怎么样?假设我有这些:上午8:00到下午12:00和下午2:00:下午6点到下午6点。 - 我如何调整您的代码?

......我告诉你的雇主我可以从事有偿工作......

好的,让我们来解决这个问题,基本上我们知道开放时间(08:00am)和关闭时间(06:00pm)给我们10个小时。我们知道至少有两个小时的休息时间(12pm-2pm),这使我们在当天有一个8小时可用的窗口。

现在,我们只需要一个算法来将尽可能多的工作量压缩到每天的可用时间,显然允许任务在上一个任务结束时开始......

再次,我们从初始数据开始......

    LocalTime openingTime = LocalTime.of(8, 0);
    LocalTime closingTime = LocalTime.of(18, 0);
    // This is a list of all the breaks, starting at to ending at
    // This way, you can add more breaks
    List<LocalTime[]> breaks = new ArrayList<>();
    breaks.add(new LocalTime[]{LocalTime.of(12, 0), LocalTime.of(14, 0)});

    LocalDate startAt = LocalDate.of(2017, Month.JANUARY, 1);

    LocalDateTime startDateTime = startAt.atTime(openingTime);

现在,我们需要计算完成工作的可用时间......

    Duration wholeDay = Duration.between(openingTime, closingTime);
    for (LocalTime[] hole : breaks) {
        wholeDay = wholeDay.minus(Duration.between(hole[0], hole[1]));
    }

然后,我们需要一些搞砸的方法来计算如何将每个作业挤进可用时间......

public LocalDateTime getDateTimeToFit(long duration, Duration wholeDay, LocalDateTime jobStartAt, LocalTime openingTime, LocalTime closingTime) {

    LocalDateTime estimatedEndTime = jobStartAt;
    do {
        // Basically, we're going to calculate out the
        // number of days and hours the job would
        // require to be completed within the available
        // time of a whole day...
        int days = (int) (duration / wholeDay.toHours());
        int hours = (int) (duration % wholeDay.toHours());
        if (hours == 0) {
            days--;
            hours += wholeDay.toHours();
        }

        estimatedEndTime = jobStartAt.plusDays(days).plusHours(hours);
        LocalDateTime closingAt = estimatedEndTime.toLocalDate().atTime(closingTime);
        // This is how much overflow there is at the end of the
        // day, if it's more than 0, we need to cycle around
        // again and squeeze some more time of the next day
        Duration fallOver = Duration.between(closingAt, estimatedEndTime);
        duration = fallOver.toHours();

        // We increment the day here simply because it's convenient
        // to do so, if we exit the loop, it won't make any
        // difference
        jobStartAt = estimatedEndTime.plusDays(1).toLocalDate().atTime(openingTime);

    } while (duration > 0);

    return estimatedEndTime;

}

根据您int[] durations = new int[]{12, 8, 15};的可用持续时间,这会给我以下输出...

2017-01-01T08:00 - 2017-01-02T12:00
2017-01-02T12:00 - 2017-01-03T10:00
2017-01-03T10:00 - 2017-01-04T17:00

现在,我警告你,这是一个&#34;概念&#34;这个想法,在我真的应该睡觉的时候深夜被砍掉了,所以你需要坐下来提出足够的测试数据和已知结果并进行适当的测试,随时调整。