首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“上周五13号”在jsr310或joda-time

“上周五13号”在jsr310或joda-time
EN

Stack Overflow用户
提问于 2012-12-14 00:47:59
回答 2查看 288关注 0票数 1

我正在尝试解析jsr310中的表达式“上个星期五13号”,不过如果你可以用Joda Time或其他库来解析,那也没问题。我走了这么远:

代码语言:javascript
复制
val builder = new DateTimeBuilder()
  .addFieldValue(ChronoField.DAY_OF_MONTH, 13)
  .addFieldValue(ChronoField.DAY_OF_WEEK, DayOfWeek.FRIDAY.getValue)

上面写着“13号星期五”好吧。但是我怎么才能从这里跳到“上星期五13号”呢?

EN

回答 2

Stack Overflow用户

发布于 2014-01-07 01:43:03

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

代码语言:javascript
复制
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的建议)。然后你可以这样使用这个调整器:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2012-12-14 18:26:17

我能想到的唯一解决方案就是倒着走这些天,然后手动检查这一天是否满足约束条件。下面是一个通用类,用于遍历时间以查找满足某些约束的DateTime

代码语言:javascript
复制
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
  }
}

然后,我可以在DateTimewith方法中使用该调整器

代码语言:javascript
复制
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    

感觉应该有一种更有效的方法来做这件事,因为约束意味着我们不必每天都走一遍,但我不确定如何实现它……

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

https://stackoverflow.com/questions/13864526

复制
相关文章

相似问题

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