首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Java8中如何跳过周末,同时向LocalDate添加天数?

在Java8中如何跳过周末,同时向LocalDate添加天数?
EN

Stack Overflow用户
提问于 2015-11-26 23:48:39
回答 4查看 49.3K关注 0票数 26

其他答案请参考Joda API。我想用java.time来做这件事。

假设今天的日期是2015年11月26日-周四,当我加上2个工作日时,我希望结果是2015年11月30日星期一。

我正在开发我自己的实现,但如果已经有了实现,那就太好了!

编辑:

除了循环之外,还有什么方法可以做到这一点吗?

我试着推导出一个函数,比如:

Y = f(X1,X2) where
Y is actual number of days to add,
X1 is number of business days to add, 
X2 is day of the week (1-Monday to 7-Sunday)

然后给定X1X2 (从日期的星期几派生),我们可以找到Y,然后使用LocalDateplusDays()方法。

到目前为止,我还不能推导出它,它并不一致。有人能确认循环直到添加所需的工作日天数是唯一的方法吗?

EN

回答 4

Stack Overflow用户

发布于 2015-12-18 02:31:01

这是一个同时支持正天数和负天数的版本,并将操作公开为TemporalAdjuster。它允许你这样写:

LocalDate datePlus2WorkingDays = date.with(addWorkingDays(2));

代码:

/**
 * Returns the working day adjuster, which adjusts the date to the n-th following
 * working day (i.e. excluding Saturdays and Sundays).
 * <p>
 * If the argument is 0, the same date is returned if it is a working day otherwise the
 * next working day is returned.
 *
 * @param workingDays the number of working days to add to the date, may be negative
 *
 * @return the working day adjuster, not null
 */
public static TemporalAdjuster addWorkingDays(long workingDays) {
  return TemporalAdjusters.ofDateAdjuster(d -> addWorkingDays(d, workingDays));
}

private static LocalDate addWorkingDays(LocalDate startingDate, long workingDays) {
  if (workingDays == 0) return nextOrSameWorkingDay(startingDate);

  LocalDate result = startingDate;
  int step = Long.signum(workingDays); //are we going forward or backward?

  for (long i = 0; i < Math.abs(workingDays); i++) {
    result = nextWorkingDay(result, step);
  }

  return result;
}

private static LocalDate nextOrSameWorkingDay(LocalDate date) {
  return isWeekEnd(date) ? nextWorkingDay(date, 1) : date;
}

private static LocalDate nextWorkingDay(LocalDate date, int step) {
  do {
    date = date.plusDays(step);
  } while (isWeekEnd(date));
  return date;
}

private static boolean isWeekEnd(LocalDate date) {
  DayOfWeek dow = date.getDayOfWeek();
  return dow == SATURDAY || dow == SUNDAY;
}
票数 11
EN

Stack Overflow用户

发布于 2015-11-27 07:49:52

确定工作日基本上是一个循环日期的问题,检查每个日期是周末还是假日。

来自OpenGamma (我是提交者)的Strata项目有一个holiday calendar的实现。API涵盖了2个工作日后查找日期的情况。该实现具有比逐日循环执行更好的optimized bitmap design。这里可能会对此感兴趣。

票数 6
EN

Stack Overflow用户

发布于 2018-03-07 07:45:10

这是一种使用java.time类、一些函数接口和lambda来添加工作日的方法……

IntFunction<TemporalAdjuster> addBusinessDays = days -> TemporalAdjusters.ofDateAdjuster(
    date -> {
      LocalDate baseDate =
          days > 0 ? date.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY))
              : days < 0 ? date.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY)) : date;
      int businessDays = days + Math.min(Math.max(baseDate.until(date).getDays(), -4), 4);
      return baseDate.plusWeeks(businessDays / 5).plusDays(businessDays % 5);
    });

LocalDate.of(2018, 1, 5).with(addBusinessDays.apply(2));
//Friday   Jan 5, 2018 -> Tuesday Jan  9, 2018

LocalDate.of(2018, 1, 6).with(addBusinessDays.apply(15));
//Saturday Jan 6, 2018 -> Friday  Jan 26, 2018

LocalDate.of(2018, 1, 7).with(addBusinessDays.apply(-10));
//Sunday   Jan 7, 2018 -> Monday  Dec 25, 2017

支持负值和从任何工作日开始!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33942544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档