Wie kann man die Anzahl der Wochen eines Monats ermitteln?

Möchte man die Anzahl an Wochen ermitteln, die von Tagen eines bestimmten Monats belegt werden, findet man erstaunlicherweise in den Java-Core-Bibliotheken und auch in der Joda-Bibliothek keine fertige Lösung. Das Beispiel geht dieses Problem an.

Eines der Hauptprobleme bei der Berechnung besteht darin, dass z.B. der Wochenbeginn (So. oder Mo.) regional unterschiedlich gesehen wird. Das Beispiel bietet eine Lösung unter Verwendung der Klasse java.util.Calendar und der Joda-Bibliothek, die für den Montag als ersten Tag der Woche gilt.
Die Berechnung folgt grob dem folgenden Prinzip:

Die Methode getAnzWochen() enthält die Berechnung. Hier werden zunächst zwei Variablen für den Monat und das Jahr belegt, die bei Verwendung der Klasse natürlich dynamisch angepasst werden können. Es ist sinnvoll, das Jahr vierstellig anzugeben, um das Jahrhundert eindeutig festzulegen.
Zwei org.joda.time.DateTime -Objekte stellen den ersten Tag und, in Kopie, ein weiteres Objekt dar, das in der Folge dazu dient, den Monat zu durchlaufen.
Mit Hilfe der Calendar -Klasse wird die Anzahl der Tage des aktuell gewählten Monats ermittelt. In der Folge muss die Anzahl der Tage festgestellt werden, die die erste Kalenderwoche belegen. Das geschieht in einer Endlosschleife, die bis zum ersten Montag zählt und dann abbricht. Die Methode DateTime#getDayOfWeek() gibt den numerischen Wochentag, beginnend mit Montag = 1 zurück. Der Wert wird in einer Variablen counter gespeichert und anschließend von der Gesamt-Tageszahl des Monats subtrahiert. Sollte der 1. des Monats bereits ein Montag sein ( counter = 0 ), so muss eine volle Woche abgezogen werden.

Die so ermittelte verbleibende Anzahl der Tage wird durch die Zahl der Tage pro Woche dividiert. So ergibt sich die Anzahl der Wochen, zu der noch die zuvor subtrahierte Woche addiert werden muss. In den meisten Fällen enthält auch die letzte Woche keine vollen 7 Tage des gefragten Monats, sondern bereits einige Tage des Folgemonats. Es muss also mit Math.ceil() aufgerundet werden. Dies kann jedoch nicht geschehen, wenn die Division bereits einen ganzzahligen Wert ergibt. In diesem Fall muss die letzte Woche somit ausdrücklich hinzugerechnet werden, allerdings nur dann, wenn die Tageszahl zwar ganzzahlig teilbar ist, aber nicht genau mit einem Sonntag endet. Letzteres ist dann der Fall, wenn der 28-tägige Februar mit einem Montag beginnt.

import java.util.Calendar;
import java.util.Locale;

import org.joda.time.DateTime;

public class WochenImMonat {

    private int getAnzWochen() {
        int year = 2010, month = 2;
        DateTime firstDay = new DateTime(year, month, 1, 0, 0);
        DateTime thisDay = firstDay;
        Calendar cal = firstDay.toCalendar(Locale.GERMANY);
        int anzDaysInMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        int counter = 0;
        while (true) {
            int monday = thisDay.getDayOfWeek();
            if (monday == 1) {
                break;
            }
            thisDay = thisDay.plusDays(1);
            ++counter;
        }
        if (counter == 0)
            counter = 7;
        double tmpDiff = anzDaysInMonth - counter;
        double ausgabe = tmpDiff / 7 + 1;
        if(ausgabe == 4.0 && anzDaysInMonth > 28)
            ausgabe = ausgabe + 1;
        return (int) Math.ceil(ausgabe);
    }

    public static void main(String[] args) {
        System.out.println(new WochenImMonat().getAnzWochen());

    }
}