考虑到从初始日期开始的工作计划,我如何生成到期日?

2022-08-21 00:00:00 java talend tmap

示例

到期时间为15分钟

日程安排

周一至周五:7:30-17:00

星期六9:00-14:00

周日10:00-13:00

如果我的初始日期(IniDate)是星期一的6:00,那么截止日期就是星期一的7:45 如果我的INDate是星期一的8:00,我的预产期是星期一的8:15,但是如果我的INDate是星期一的16:50,我的预产期是星期二的7:35,因为我离星期一有10分钟,离第二天有5分钟,另外,如果我的INDate是星期一的18:00,我的预产期是星期二的7:45,在Talend Open Studio中使用Java进行数据集成,这将使用实际日期。这意味着假设我的初始日期是2020年5月5日18:00,那么我的预产期将是2020年6月5日7:45,考虑到时间表,这是我的第一个问题,尝试在中间变量部分的TMap组件中使用它。


解决方案

将您的到期时间表示为Duration

Duration dueTime = Duration.ofMinutes(15);
将您的日程表表示为EnumMap<DayOfWeek, DailySchedule>,其中DailySchedule是您为每天的开放和关闭时间编写的类。在类内部将时间表示为LocalTime对象。该类可能具有用于确定给定时间是在计划间隔之前、之内还是之后的方法。

最好将您的初始时间05/05/2020 18:00表示为相关时区的ZonedDateTime(LocalDateTime可能也可以,但确实不适合此目的)。

给出你最初的日期和时间,去掉星期几。在地图上查一查日程表。如果时间不在计划间隔内,请首先根据需要将其调整为今天或明天的间隔开始时间。

在您的到期日期和时间中的第一个快照是调整后的日期和时间加上到期时间。ZonedDateTime具有接受Durationplus方法。现在,如果到期日期在下一个日期或在今天的关闭时间之后,这是不正确的。在本例中,使用Duration.between计算一天可以花费多少时间(示例中的10分钟)。从到期时间(Duration.minus())中减去此值。现在从第二天的开放时间开始。检查真的应该在循环中进行,以考虑到每天的时间表可能比预期时间短。如果周六的日程安排为09:00-09:05,周日的日程安排为10:00-10:05,我们可能不得不从周五循环到周一,然后才能找到正确的截止日期和时间。

DurationDayOfWeekLocalTimeZonedDateTime都属于现代Java日期和时间API java.time。位于底部的教程链接。

稍后编辑:代码

我可能会这样做:

Map<DayOfWeek, DailySchedule> weeklySchedule = new EnumMap<>(DayOfWeek.class);
DailySchedule weekdaySchedule
        = new DailySchedule(LocalTime.of(7, 30), LocalTime.of(17, 0));
for (DayOfWeek dow = DayOfWeek.MONDAY;
        dow.getValue() <= DayOfWeek.FRIDAY.getValue(); dow = dow.plus(1)) {
    weeklySchedule.put(dow, weekdaySchedule);
}
weeklySchedule.put(DayOfWeek.SATURDAY,
        new DailySchedule(LocalTime.of(9, 0), LocalTime.of(14, 0)));
weeklySchedule.put(DayOfWeek.SUNDAY,
        new DailySchedule(LocalTime.of(10, 0), LocalTime.of(13, 0)));

Duration dueTime = Duration.ofMinutes(15);

// Set initial day and time
DayOfWeek currentDay = DayOfWeek.MONDAY;
LocalTime currentTime = LocalTime.of(16, 50);
Duration remainingTimeToAdd = dueTime;

DailySchedule todaysSchedule = weeklySchedule.get(currentDay);
if (todaysSchedule.isBeforeOpen(currentTime)) {
    currentTime = todaysSchedule.getOpen();
} else if (todaysSchedule.isOnOrAfterClose(currentTime)) {
    currentDay = currentDay.plus(1);
    todaysSchedule = weeklySchedule.get(currentDay);
    currentTime = todaysSchedule.getOpen();
}
// We will break this loop explicitly when done
while (true) {
    // Can time be added today?
    LocalTime candidateDueTime = currentTime.plus(remainingTimeToAdd);
    if (todaysSchedule.isWithinSchedule(candidateDueTime)) {
        // yes, done
        currentTime = candidateDueTime;
        break;
    } else {
        // take remainder of today and continue tomorrow
        remainingTimeToAdd = remainingTimeToAdd.minus(Duration.between(currentTime, todaysSchedule.getClose()));
        currentDay = currentDay.plus(1);
        todaysSchedule = weeklySchedule.get(currentDay);
        currentTime = todaysSchedule.getOpen();
    }
}

System.out.println("Due day and time: " + currentDay + " at " + currentTime);

示例的输出:

截止日期和时间:星期二07:35

如果到期时间足够长,从一天关闭到第二天打开,代码将不起作用。并且缺少各种验证和检查,您将需要添加它们。

链接

Oracle tutorial: Date Time解释如何使用java.time。

相关文章