2012-12-13 29 views
1

我试图解决表达“上周五13日”jsr310,但如果你可以在乔达时间或其他图书馆做到这一点,那很好太。我得到了这个:“上周五13日”在jsr310或joda-time

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

这似乎指定“星期五第13”好吧。但是我怎样才能从此到“上周五13日”呢?

回答

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方法DateTime的:

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  

感觉就像应该有一个更有效的方法来做到这一点,因为约束意味着我们不必每天都在步行,但我不知道如何实现...

1

在这里每月iter (记住两个这样的日期之间不能超过14个月),这可能比每日迭代解决方案更好。我把它写在JSR-310的基地,在纯Java - 没有测试,因此无法保证(我不知道写斯卡拉所以你要它适应您的需求):

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(应该或多或少地直接)。

+0

这对于13号星期五的特定问题肯定更有效。尽管如此,它并没有很好地概括任何其他领域。例如,如果我切换到“DAY_OF_YEAR”而不是“DAY_OF_MONTH”,或者如果我添加了另一个约束,就像它也必须在2月份一样,您的代码不能直接使用。 – Steve

+0

是的,具体说明DAY_OF_MONTH和DAY_OF_WEEK的组合预计将配置调节器。对于其他条件,无论如何还需要另一种算法 - 由于我们日历的不规则性而导致最终后果。有无限的可能性。没有图书馆可以提供全部,但是你可以自由地为你的具体问题编写自己的调节器。 –

+0

请注意,对于我给这个问题的答案,您不需要为每个问题编写一个新的调整器 - 它将处理任何类型的单位和任何数量的约束。但要使其像每个问题的自定义编码解决方案一样高效,可能相当困难。 – Steve

相关问题