我正在尝试解析jsr310中的表达式“上个星期五13号”,不过如果你可以用Joda Time或其他库来解析,那也没问题。我走了这么远:
val builder = new DateTimeBuilder()
.addFieldValue(ChronoField.DAY_OF_MONTH, 13)
.addFieldValue(ChronoField.DAY_OF_WEEK, DayOfWeek.FRIDAY.getValue)上面写着“13号星期五”好吧。但是我怎么才能从这里跳到“上星期五13号”呢?
发布于 2014-01-07 01:43:03
这里是一个每月迭代的解决方案(请记住,两个这样的日期之间不能超过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 (或多或少应该是直接的)。
发布于 2012-12-14 18:26:17
我能想到的唯一解决方案就是倒着走这些天,然后手动检查这一天是否满足约束条件。下面是一个通用类,用于遍历时间以查找满足某些约束的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
}
}然后,我可以在DateTime的with方法中使用该调整器
val lastFridayThe13th = LocalDate.of(2012, 12, 12).`with`(new PreviousAdjuster(
ChronoField.DAY_OF_MONTH -> 13,
ChronoField.DAY_OF_WEEK -> DayOfWeek.FRIDAY.getValue))
println(lastFridayThe13th) // prints 2012-07-13 感觉应该有一种更有效的方法来做这件事,因为约束意味着我们不必每天都走一遍,但我不确定如何实现它……
https://stackoverflow.com/questions/13864526
复制相似问题