在jsr310或joda-time,“上周五13日”

时间:2012-12-13 16:47:59

标签: jodatime jsr310

我正试图解决jsr310中“上周五13日”的表达,但如果你能在Joda Time或其他图书馆中这样做,那也没关系。我到目前为止:

val builder = new DateTimeBuilder()
  .addFieldValue(ChronoField.DAY_OF_MONTH, 13)
  .addFieldValue(ChronoField.DAY_OF_WEEK, DayOfWeek.FRIDAY.getValue)

这似乎指明“星期五十三号”没关系。但是我怎么从这个到“上周五13”呢?

2 个答案:

答案 0 :(得分:1)

这里是一个月度迭代解决方案(记住两个这样的日期之间不能超过14个月),这可能比每日迭代解决方案更好。我在JSR-310的基础上用纯Java编写它 - 未经测试,因此无法保证(我不知道编写Scala所以你必须根据自己的需要调整它):

public static final TemporalAdjuster LAST_FRIDAY_13 = (Temporal temporal) -> {
  LocalDate test = LocalDate.from(temporal);

  // move to last 13th of month before temporal
  if (test.getDayOfMonth() <= 13) {
    test = test.minus(1, ChronoUnit.MONTHS);
  }

  test = test.withDayOfMonth(13);

  // iterate monthly backwards until it is a friday
  while (test.getDayOfWeek() != DayOfWeek.FRIDAY) {
    test = test.minus(1, ChronoUnit.MONTHS);
  }

  return test;
}

请注意,调整器存储为静态常量(规范主管Stephen Colebourne也推荐)。然后你可以这样使用这个调整器:

System.out.println(LocalDate.of(2012, 12, 12).with(LAST_FRIDAY_13));
// Output: 2012-07-13

顺便说一句,您还要求在其他库中提供解决方案。好吧,如果你可以等几周(3-4),那么我将使用我的new time library提供一个非常类似的解决方案,只需要Java 6+。而且你肯定可以将显示的代码翻译成JodaTime(应该或多或少地直接)。

答案 1 :(得分:0)

我能想出的唯一解决方案就是向后走,然后手动检查当天是否满足约束条件。这是一个通用课程,用于查找符合某些约束条件的DateTime

class PreviousAdjuster(constraints: (DateTimeField, Int)*) extends WithAdjuster {
  val unit = constraints.map(_._1.getBaseUnit).minBy(_.getDuration)
  def doWithAdjustment(dateTime: DateTime): DateTime = {
    var curr = dateTime
    while (constraints.exists{case (field, value) => curr.get(field) != value}) {
      curr = curr.minus(1, unit)
    }
    curr
  }
}

然后我可以在with的{​​{1}}方法中使用该调整器:

DateTime

感觉应该有更有效的方法来做到这一点,因为限制意味着我们不必每天都要走过,但我不确定如何实现......