Pergunta

I'm trying to iterate over a range of weekdays, where each weekday maps to an integer (Sunday = 1, Monday = 2, ..., Saturday = 7).

The range is defined by a start and end day. This is fine for a start and end day like Monday(2) - Thursday(5), as I can just do:

for(int i = startDay; i <= endDay; i++) { ... } 

I'm having difficulty when the range is split across the end and start of a week, like Friday(6) - Monday(2). This obviously doesn't work with the above for loop - e.g.

for(int i = 6; i <= 2; i++) { ... }    // wouldn't even execute once. 

The only solution I can see is implementing some sort of circular buffer, which I feel is overkill for such a simple problem. I'm just stumped, and most likely missing something obvious here. I think a solution may have something to do with modular arithmetic, but I'm not quite sure.

Foi útil?

Solução

You can do:

int numberOfDays = endDay >= startDay ? endDay - startDay : 8 - (startDay - endDay);
for (int i = startDay; i <= startDay + numberOfDays; i++) {
    int day = (i - 1) % 7 + 1;
}

This makes use of the % modulo operator to ensure all values remain within 1 - 7.

For example, once i becomes 8 the calculation will wrap day back to 1: (8 - 1) % 7 + 1 == 1.

Outras dicas

It's probably clearest just to use a break, then you don't have to worry about all the different cases:

for (int day = startDay; ; day = (day - 1) % 7 + 1) {
    // ... do your stuff
    if (day == endDay) {
        break;
    }
}

or, some might prefer this:

int day = startDay;
while (true) {
    // ... do something
    if (day == endDay) {
        break;
    }
    day = (day - 1) % 7 + 1;
}

or:

int day = startDay;
while (true) {
    // ... do something
    if (day == endDay) {
        break;
    }
    if (++day > 7) {
        day = 1;
    }
}

Trying to get all the different cases right with a for loop can be a headache. You have to make sure these are handled:

startDay == 1, endDay == 7
endDay == startDay
endDay == startDay - 1  (which should go through every day of the week in some order)
endDay > startDay
endDay < startDay

In Java 8:

// input section
DayOfWeek start = DayOfWeek.FRIDAY;
DayOfWeek end = DayOfWeek.MONDAY;

// execution section
DayOfWeek dow = start;
DayOfWeek stop = end.plus(1);

do {
  // ... your code
  dow = dow.plus(1);
} while (dow != stop);

The do-while-construction ensures that for the condition start == end the loop will be executed at least once.

UPDATE due to use of your localized indices (Sunday = 1 instead of 7)

You can convert the indices to DayOfWeek-objects this way:

private static DayOfWeek convert(int localIndex) {
  int iso = localIndex - 1;
  if (iso == 0) {
    iso = 7;
  }
  return DayOfWeek.of(iso);
}

You can use a % operator for some sort of circularity

 for (int i=6; i!=2; i=(i+1)%7) { ... }

That will index days from 0, so Sunday = 0 ... Saturday = 6. If you really want to have index starting from 1 it's only interpretation problem. You can for example do:

 for (int i=6; i!=2; i=(i+1)%7) { 
     int day=i+1; 
     // use day here
 }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top