Reputation: 1807
In my Android app i'm using the following Map
to map the days of the Calendar
class to String
s:
Map<Integer, String> map = new HashMap<>(7);
// values of the Calendar field
map.put(Calendar.MONDAY, "Mon"); // 2
map.put(Calendar.TUESDAY, "Tue"); // 3
map.put(Calendar.WEDNESDAY, "Wed"); // 4
map.put(Calendar.THURSDAY, "Thu"); // 5
map.put(Calendar.FRIDAY, "Fri"); // 6
map.put(Calendar.SATURDAY, "Sat"); // 7
map.put(Calendar.SUNDAY, "Sun"); // 1
And adding Button
s dynamically to a LinearLayout
with the day text like this:
LinearLayout dayLayout = (LinearLayout) findViewById(R.id.layout_days);
for(int i = 1; i <= 7; i++) {
Button button = new Button(this);
button.setText(map.get(i));
dayLayout.addView(button);
}
This works fine, but the list of Button
s always start from Sunday regardless of the current Locale
.
I'm trying to rewrite this loop so it takes the first day of the week into account.
Something like this:
LinearLayout dayLayout = (LinearLayout) findViewById(R.id.layout_days);
int firstDayOfWeek = Calendar.getInstance().getFirstDayOfWeek();
for(int i = firstDayOfWeek; i <= 7; ???) { // this is where i'm stuck
Button button = new Button(this);
button.setText(map.get(i));
dayLayout.addView(button);
}
The problem is i cannot figure out the correct formula for fetching the days in the correct order.
If the first day of the week is Monday, the loop has to go as 2 3 4 5 6 7 1
.
I guess i have to play with the modulo operator, i just don't know how.
I'd really appreciate any advice, maybe my approach is completely wrong.
Upvotes: 3
Views: 2242
Reputation: 124704
First of all, you should not use the numeric values of the Calendar.*
constants.
The numeric values are implementation detail, not API, and should not be used directly like the for-loop tries.
It will be better to store the constants in a list:
List<Integer> days = Arrays.asList(
Calendar.MONDAY,
Calendar.TUESDAY,
Calendar.WEDNESDAY,
Calendar.TUESDAY,
Calendar.FRIDAY,
Calendar.SATURDAY,
Calendar.SUNDAY
);
And then find the index whose value corresponds to firstDayOfWeek
:
int start = days.indexOf(firstDayOfWeek);
And then, create the correct map key by rotating the 0..6 indexes by the value of start
and the modulo operator, like this:
for(int i = 0; i < 7; i++) {
int key = days.get((start + i) % 7);
Button button = new Button(this);
button.setText(map.get(key));
dayLayout.addView(button);
}
Upvotes: 2
Reputation: 6495
Here is a complete example that also removes the need for the Map so that weekdays are displayed in correct locale.
DateFormatSymbols symbols = new DateFormatSymbols(Locale.getDefault());
// Array with 8 elements (first is empty string), so Calendar constants correspond to the day.
String[] dayNames = symbols.getShortWeekdays();
int firstDayOfWeek = Calendar.getInstance().getFirstDayOfWeek();
int daysStart = Calendar.SUNDAY;
int daysEnd = Calendar.SATURDAY;
int dayCount = (daysEnd - daysStart) + 1; // +1 because both ends inclusive
for(int i = 0; i < dayCount; i++) {
int day = firstDayOfWeek + i;
if(day > daysEnd) // loop back if over the end
day -= dayCount;
Button button = new Button(this);
button.setText(dayNames[day]);
dayLayout.addView(button);
}
Day starts at firstDayOfWeek: 2 3 4 5 6 7 1
English: Mon Tue Wed Thu Fri Sat Sun
Japanese: 月 火 水 木 金 土 日
Upvotes: 0
Reputation: 69318
Isn't this what you want?
Map<String, Integer> names = (new GregorianCalendar()).getDisplayNames(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.ENGLISH);
which gives
Tue, 3
Thu, 5
Sun, 1
Sat, 7
Wed, 4
Mon, 2
Fri, 6
Upvotes: 0
Reputation: 30284
Define an array like this:
int[] daysInWeek = [2, 3, 4, 5, 6, 7, 1]
Then solution should be:
// define day of week you want to print out first.
int firstDayOfWeekIndex = 0; // print Monday first
for (int i = 0; i < 7; i++) {
int currentDay = (firstDayOfWeekIndex + i) % 7;
String day = map.get(daysInWeek[currentDay]);
// print this day to your button
Button button = new Button(this);
button.setText(day);
dayLayout.addView(button);
}
Upvotes: 0
Reputation: 196
maybe add a count into the for loop and compare count to 7, so that the loop will go through all 7 days regardless of the start.
so maybe something like this
LinearLayout dayLayout = (LinearLayout) findViewById(R.id.layout_days);
int firstDayOfWeek = Calendar.getInstance().getFirstDayOfWeek();
int count = 1;
for(int i = firstDayOfWeek; count <= 7; i++) {
count++
if(i <= 7)
firstDayOfWeek = 1;
Button button = new Button(this);
button.setText(map.get(i));
dayLayout.addView(button);
}
Upvotes: 0
Reputation: 15704
Starting with an i
as 1 2 3 4 5 6 7
,
you can take these mod 7, giving 1 2 3 4 5 6 0
and then add 1: giving 2 3 4 5 6 7 1
.
Upvotes: 0