2011-11-30 86 views
6

有没有一种优雅的方式可以使用JodaTime为给定日期查找一周中最近的一天?我最初认为setCopy()就是这样,但是这一天设置在同一周的特定日期。因此,如果ld2011-11-27day是“星期一”,则下面的函数会根据需要返回2011-11-21,而不是2011-11-28如何找到最近的一个星期的任意日期?

// Note that "day" can be _any_ day of the week, not just weekdays. 
    LocalDate getNearestDayOfWeek(LocalDate ld, String day) { 
     return ld.dayOfWeek().setCopy(day); 
    } 

所需的输出为各种输入:

2011-12-04, Monday => 2011-12-05 
2011-12-04, Tuesday => 2011-12-06 
2011-12-04, Wednesday => 2011-12-07 
2011-12-04, Thursday => 2011-12-01 
2011-12-04, Friday => 2011-12-02 
2011-12-04, Saturday => 2011-12-03 
2011-12-04, Sunday => 2011-12-04 

2011-12-05, Monday => 2011-12-05 
2011-12-05, Tuesday => 2011-12-06 
2011-12-05, Wednesday => 2011-12-07 
2011-12-05, Thursday => 2011-12-08 
2011-12-05, Friday => 2011-12-02 
2011-12-05, Saturday => 2011-12-03 
2011-12-05, Sunday => 2011-12-04 

下面是一个变通,我想出了的作品在我目前的状况特定的限制,但我很想得到帮助寻找一个通用的完全通用的解决方案。

LocalDate getNearestDayOfWeek(LocalDate ld, String day) { 
     LocalDate target = ld.dayOfWeek().setCopy(day); 
     if (ld.getDayOfWeek() > DateTimeConstants.SATURDAY) { 
      target = target.plusWeeks(1); 
     } 
     return target; 
    } 
+0

的可能重复[乔达 - 时间:?如何获得下周五(http://stackoverflow.com/questions/1636038/joda-time-如何得到下一个星期五) – 2011-11-30 06:09:39

+2

我不这么认为。找到_next_天,但我想找到_nearest_天。 –

+0

您需要定义“最近的”和“平日”的含义,以便能够提供正确的答案。也许是预期投入到产出的表格? – JodaStephen

回答

5

在Jodatime,这种事情应该是可行的三条,四线:

/** Given a reference LocalDate and a day of week, eg DateTimeConstants.MONDAY 
     Returns the nearest date with that day of week */ 
    public static LocalDate getNearestDayOfWeek(LocalDate t0,int dow) { 
     LocalDate t1 = t0.withDayOfWeek(dow); 
     LocalDate t2 = t1.isBefore(t0) ? t1.plusWeeks(1) : t1.minusWeeks(1); 
     return Math.abs(Days.daysBetween(t1, t0).getDays()) < 
       Math.abs(Days.daysBetween(t2, t0).getDays()) ? t1 : t2; 
    } 

或者更紧凑,更高效:

public static LocalDate getNearestDayOfWeek(LocalDate t0, int dow) { 
    LocalDate t1 = t0.withDayOfWeek(dow); 
    if (t1.isBefore(t0.minusDays(3)))  return t1.plusWeeks(1); 
    else if (t1.isAfter(t0.plusDays(3))) return t1.minusWeeks(1); 
    else return t1; 
} 

如果你想通过星期作为字符串:

public static LocalDate getNearestDayOfWeek(LocalDate t0, String dow) { 
    return getNearestDayOfWeek(t0,t0.dayOfWeek().setCopy(dow).getDayOfWeek()); 
} 

示例:

// prints 2011-11-28 
    public static void main(String[] args) throws Exception { 
     LocalDate today = new LocalDate(2011,11,27); 
     int dow = DateTimeConstants.MONDAY; 
     System.out.println(getNearestDayOfWeek(today ,dow)); 
    } 
+0

这很好。 字符串在我的特殊情况下很有意义。 (我正在处理配置文件中的日期字符串的名称。)我同意这不是一般情况下最好的。 –

1

这是一个解决问题的方法。我对JodaTime有一点了解,但不是所有的类和方法。我假设给定一个日期,你可以得到星期几和下一个或前一个日期。

有三种情况。

  1. dayOfTheWeek对于特定的日期是一个工作日。归期。
  2. dayOfTheWeek是星期六。从你的日期减去1天。返回日期 - 1天。
  3. The dayOfTheWeek是星期日。为你的约会添加1天。返回日期+一天。

如果 dayOfTheWeek是枚举类型,那么case语句会处理以直接的方式任务。

+0

我想你误解了我的问题。你的算法似乎找到最近的工作日,这不是我想要的。相反,对于任何给定的日期,我希望能够问“最近的星期一?星期二?星期六?”我编辑了我的问题以清楚地说明问题。 –

+0

@ stig-brautaset:是的,我做过了。我想我可能会在写答案的时候得出答案,但认为错误的答案可能有助于得到一个正确的答案:-)我稍后再试。 –

1

这通过定义一周中最近几天的时间间隔来查找一周中最近的一天。乔达定义为星期一开始的一周。所以如果今天是星期二而星期几是星期日,那么日期将是下个星期日,而不是前一天。如果一周中的第一天重新定义为星期日,则返回的日期将为前一个星期日。以下代码不受一周中第一天的定义影响。

 
DateTime getNearestDayOfWeek(DateTime dateTime, String day) { 
    //Create an interval containing the nearest days of the week. 
    DateTime begin = dateTime.minusHours(DateTimeConstants.HOURS_PER_WEEK/2).dayOfWeek().roundHalfCeilingCopy(); 
    DateTime end = dateTime.plusHours(DateTimeConstants.HOURS_PER_WEEK/2).dayOfWeek().roundHalfCeilingCopy(); 
    Interval interval = new Interval(begin, end); 

    //Adjust nearest day to be within the interval. Doesn't depend on definition of first day of the week. 
    DateTime nearest = dateTime.dayOfWeek().setCopy(day); 
    if (interval.isAfter(nearest)) //nearest is before the interval 
    return nearest.plusWeeks(1); 
    else if (interval.isBefore(nearest)) //nearest is after the interval 
    return nearest.minusWeeks(1); 
    else 
    return nearest; 
} 
+0

一个有趣的替代方式去了解它。 –

2

就像这样。对于dayOfWeek参数,请使用org.joda.time中定义的常量。DateTimeConstants:

public LocalDate getNext(int dayOfWeek) { 
    LocalDate today = new LocalDate(); 
    return getNext(dateOfWeek, today); 
} 

public LocalDate getNext(int dayOfWeek, LocalDate fromDate) { 
    int dayOffset = DateTimeConstants.DAYS_PER_WEEK - dayOfWeek + 1; 
    LocalDate weekContainingDay = fromDate.plusDays(dayOffset); 

    return weekContainingDay.withDayOfWeek(dayOfWeek); 
} 

用法:

LocalDate nextSunday = foo.getNext(DateTimeConstants.SUNDAY); 
相关问题