在开始,结束日期之间的所有周内迭代

时间:2013-08-28 12:32:17

标签: java datetime

我有两个Date对象,start和finish。我想每周迭代它们,即如果它们之间恰好有4周(日历周,而不是彼此之后的7天),我想要4次迭代,并且在每次迭代中我想得到实际的开始和结束日期

我目前正在为此目的修改一个Iterable,但我在考虑是否可以使用例如Joda Time或智能自定义方法轻松实现。 提前谢谢!

编辑:我必须重申,我需要几周时间,而不是七天后。如果我的开始日期是一周中的随机日(例如星期五),我的第一次迭代应包含[周五,周日]而不是[周五,周五+ 7天]。解决方案发布为答案。

3 个答案:

答案 0 :(得分:0)

使用日历和WEEK_OF_YEAR进行计算:

 int startWeek;
 int finishWeek;
 int diff;
 SimpleDateFormat sdf;
 Calendar cal;
 Calendar startCountingCal;
 Date startDate;
 Date finishDate;
 String startDateS = "01/01/2013";
 String finishDateS = "01/05/2013";

 sdf = new SimpleDateFormat("dd/MM/yyyy");

 startDate = sdf.parse(startDateS);
 finishDate = sdf.parse(finishDateS);

 cal = Calendar.getInstance();

 cal.setTime(startDate);
 startWeek = cal.get(Calendar.WEEK_OF_YEAR);    

 cal.setTime(finishDate);
 finishWeek = cal.get(Calendar.WEEK_OF_YEAR);

 diff = finishWeek - startWeek;

 startCountingCal = Calendar.getInstance();
 startCountingCal.setTime(startDate);   

 for (int i = 0; i < diff; i++) {

     if (i==0) {
        System.out.println("WEEK " + i + " start: " + sdf.format(startCountingCal.getTime()));
        startCountingCal.add(Calendar.DATE, 7);
        System.out.println("WEEK " + i + " start: " + sdf.format(startCountingCal.getTime()));  
    } else {
        System.out.println("WEEK " + i + " start: " + sdf.format(startCountingCal.getTime()));
        startCountingCal.add(Calendar.DATE, 7);
        System.out.println("WEEK " + i + " start: " + sdf.format(startCountingCal.getTime()));  
    }

}

输出:

WEEK 0 start: 01/01/2013
WEEK 0 start: 08/01/2013
WEEK 1 start: 08/01/2013
WEEK 1 start: 15/01/2013
WEEK 2 start: 15/01/2013
WEEK 2 start: 22/01/2013
WEEK 3 start: 22/01/2013
WEEK 3 start: 29/01/2013
....
etc.

希望它有所帮助!

答案 1 :(得分:0)

谢谢大家,这是一个满足我要求的工作解决方案(请注意,在大多数情况下,在某些日子里添加七天不会产生日历周,只有在周一!) 此代码使用Joda Time API。

private static List<Interval> getWeeks(final DateTime start, final DateTime finish)
{
    final int weekLeaps = Weeks.weeksBetween(start, finish).getWeeks();
    if (weekLeaps == 0) {
        return ImmutableList.of(new Interval(start, finish));
    } else {
        // We hop sundays at least once
        final ImmutableList.Builder<Interval> resBuild = ImmutableList.<Interval> builder();

        // First week
        DateTime wStart = start;
        DateTime wEnd = rollToWeekEnd(start);
        resBuild.add(new Interval(wStart, wEnd));

        // Other weeks
        for (int i = 0; i < weekLeaps; i++) {
            wStart = wEnd.plusSeconds(1);
            DateTime actWeekEnd = rollToWeekEnd(wStart);
            wEnd = actWeekEnd.isBefore(finish) ? actWeekEnd : finish;
            resBuild.add(new Interval(wStart, wEnd));
        }

        return resBuild.build();
    }
}

private static DateTime rollToWeekEnd(final DateTime from)
{
    return from.withDayOfWeek(DateTimeConstants.SUNDAY)
        .withHourOfDay(23)
        .withMinuteOfHour(59)
        .withSecondOfMinute(59)
        .withMillisOfSecond(0);
}

答案 2 :(得分:0)

在Java 9中有一个很好的LocalDate.datesUntil方法。还可以使用TemporalAdjusters在一周内调整时间的简便方法。

    int numOfWeeks = 4;

    // First iteration with alignment
    LocalDate start = LocalDate.now();
    LocalDate endOfTheFirstWeek = start.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
    out.println(String.format("[%s,%s]", start, endOfTheFirstWeek));

    // Remaining iterations
    endOfTheFirstWeek
            .datesUntil(endOfTheFirstWeek.plusWeeks(numOfWeeks - 1), Period.ofWeeks(1))
            .forEach(it -> {
                LocalDate from = it.plusDays(1);
                LocalDate to = from.plusWeeks(1);
                out.println(String.format("[%s,%s]", from, to));
            });