I've made a function that should get the number of weeks for a given month. For January, May, July and October, it should return 5 weeks. However, it returns 5 for March, June, September. and November. Surprisingly, the total amount of weeks are correct (52).
public static int getNofWeeksWithFirstWeekStartingWhenFirstDayOfMonthOccurs(Calendar calendar) {
while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
calendar.roll(Calendar.DATE, true);
}
int currentMonth = calendar.get(Calendar.MONTH);
int nextMonth = (currentMonth + 1) % 12;
int prePreviousMonth = (currentMonth + 12 - 2) % 12;
int nofWeeks = 0;
do {
int month = calendar.get(Calendar.MONTH);
if (month == nextMonth) {
nofWeeks++;
}
if (month == prePreviousMonth) {
break;
}
calendar.roll(Calendar.WEEK_OF_YEAR, true);
} while (true);
return nofWeeks;
}
public static void main(String[] args) {
int numWeeks;
int totalWeeks=0;
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2016);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.MONTH, Calendar.MAY);
numWeeks=getNofWeeksWithFirstWeekStartingWhenFirstDayOfMonthOccurs(calendar);
System.out.println("no of weeks " + numWeeks);
}
Output: no of weeks 4
Month start is in Week that has first day. e.g.:
25 - 1 May
2 - 8 May
9 - 15 May
16 - 22 May
23 - 29 May
5 Weeks in May:
It sounds to me like you should:
There's no need to do half the work you're currently doing.
Using java.util.Calendar
, it would be something like:
// Note: day-of-week runs from Sunday (1) to Saturday (7).
// Entry 0 here is not used. We could do this without an array lookup
// if desired, but it's whatever code you think is clearest.
private static final int[] EXTRA_DAYS = { 0, 6, 0, 1, 2, 3, 4, 5 };
// Note: 0-based month as per the rest of java.util.Calendar
public static int getWeekCount(int year, int month) {
Calendar calendar = new GregorianCalendar(year, month, 1);
int dayOfWeekOfStartOfMonth = calendar.get(Calendar.DAY_OF_WEEK);
int extraDays = EXTRA_DAYS[dayOfWeekOfStartOfMonth];
int regularDaysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
int effectiveDaysInMonth = regularDaysInMonth + extraDays;
return effectiveDaysInMonth / 7;
}
If at all possible, I'd recommend using Joda Time or java.time
instead, however.
With that code, the results for 2016 are:
See more on this question at Stackoverflow