【问题标题】:How can I generate a due date considering a work schedule from a initial date?考虑到从初始日期开始的工作计划,我如何生成截止日期?
【发布时间】:2020-08-20 17:12:34
【问题描述】:

例子

截止时间为 15 分钟

时间表

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

周六 9:00 - 14:00

周日 10:00 - 13:00

如果我的初始日期 (IniDate) 是星期一 6:00,则截止日期将是星期一 7:45 如果我的 IniDate 是星期一 8:00,我的到期日将是星期一 8:15,但如果我的 IniDate 是星期一 16:50,我的到期日将是星期二 7:35,因为我有 10 分钟的时间星期一和第二天之后的 5 分钟,如果我的 IniDate 是星期一 18:00,我的截止日期将是星期二 7:45,在 Talend Open Studio 中使用 Java 进行数据集成,这将使用实际日期,这意味着假设我的 IniDate 是 05/05/2020 18:00 那么我的截止日期将是 06/05/2020 7:45,考虑到日程安排,这是我的第一个问题,试图在tMap 组件在中间的变量部分。

【问题讨论】:

标签: java talend tmap


【解决方案1】:

Duration表示你的到期时间:

Duration dueTime = Duration.ofMinutes(15);

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

最好将您的初始时间 2020 年 5 月 5 日 18:00 表示为相关时区中的 ZonedDateTimeLocalDateTime 也可以工作,但实际上不正确)。

给定您的初始日期和时间,从中取出星期几。在地图中查找每日时间表。如果时间不在计划间隔内,请先将其调整为今天或明天的间隔开始。

到期日期和时间的第一枪是调整后的日期和时间加上到期时间。 ZonedDateTime 有一个接受Durationplus 方法。现在,如果到期日在下一个日期或在今天的截止时间之后,这是不正确的。在这种情况下,使用Duration.between 计算您一天可以花费多少时间(在您的示例中为 10 分钟)。从到期时间中减去这个 (Duration.minus())。现在从第二天的开放时间开始。检查实际上应该循环完成,以考虑到每日计划可能比到期时间短。如果周六的时间表是 09:00-09:05 和周日 10:00-10:05,我们可能需要从周五循环到周一才能找到正确的截止日期和时间。

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

稍后编辑:代码

我可能会这样做:

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。

【讨论】:

    最近更新 更多