我想计算事件的结束日期(和时间)。我知道开始日期和持续时间(以分钟为单位)。但:
- 我必须跳过假期 - 非经常性情况
- 我不得不跳过周末 - 反复出现的情况
- 我必须不计算工作时间(例如:从上午 8:00 到下午 5:00) - 经常出现的情况,但粒度更细
有没有一种简单的方法可以使用 Joda 时间库来实现这些案例?
你看过假期计算项目吗?它出现在 jodatime 的相关项目中,可能很有用
Jodatime 会帮助你 - 我会说很多 - 但你需要自己编写逻辑,一个循环跳过一整天和一天中的某些时间。在我看来,不是很简单,也不是很复杂。
首先,您必须定义“假期”。并非每个语言环境都具有相同的语言环境,因此必须使其具有通用性和可插入性。
我不认为这很“简单”。
这是我使用的一些代码。dtDateTimes
可以包含您预定义的假期日期(例如英国银行假期),并且dtConstants
可以包含您想要匹配的经常性事物,例如DateTimeConstants.SATURDAY
.
/**
* Returns a tick for each of
* the dates as represented by the <code>dtConstants</code> or the list of <code>dtDateTimes</code>
* occurring in the period as represented by begin -> end.
*
* @param begin
* @param end
* @param dtConstants
* @param dtDateTimes
* @return
*/
public int numberOfOccurrencesInPeriod(final DateTime begin, final DateTime end, List<Integer> dtConstants, List<DateTime> dtDateTimes) {
int counter = 0;
for (DateTime current = begin; current.isBefore(end); current = current.plusDays(1)) {
for (Integer constant : dtConstants) {
if (current.dayOfWeek().get() == constant.intValue()) {
counter++;
}
}
for (DateTime dt : dtDateTimes) {
if (current.getDayOfWeek() == (dt.getDayOfWeek())) {
counter++;
}
}
}
return counter;
}
/**
* Returns true if the period as represented by begin -> end contains any one of
* the dates as represented by the <code>dtConstants</code> or the list of <code>dtDateTimes</code>
*
* @param begin
* @param end
* @param dtConstants
* @param dtDateTimes
*/
public boolean isInPeriod(final DateTime begin, final DateTime end, List<Integer> dtConstants, List<DateTime> dtDateTimes) {
return numberOfOccurrencesInPeriod(begin, end, dtConstants, dtDateTimes) > 0;
}