4. März 2024

Die Kalenderwoche in JavaScript berechnen

Aus aktuellem Anlass: Wie berechnet man in JavaScript eine Kalenderwoche?

 

In einem unserer aktuellen Projekte wurde in Angular eine JavaScript eine Funktion benötigt, die auf Basis eines Datum die aktuelle Kalenderwoche berechnet. Schnell gegoogelt und reichlich Beispiele gefunden, die leider alle buggy waren, da keine die KW 1 / KW 53 richtig berechnete. Also habe ich auf Basis dieses wikipedia Eintrages folgende Codezeilen zusammengefasst für den Fall, dass jemand vor dem gleichen Problem steht:

Was die Funktion nicht macht: Sie berechnet nicht den Sonderfall einer KW 54. Die gibt es tatsächlich. Und sie geht davon aus, das der Wochenerste immer ein Montag ist. Wer das anders benötigt, kann den entspr. Offset einbauen oder sich gerne einfach per Mail bei uns melden:

kontakt[at]itbalance.de.

 

Viel Spass damit !!!

function getWeek(d){

    if (!d) {
        return 0;
    }

    let date;
    if (d instanceof Date) {
        date = new Date(d.getTime());
    } else {
        // deliver JSON Date
        const x = d.split('-');
        date = new Date(x[0], x[1] - 1, x[2], 11); // 11 = independent of time zone date switch
    }
    // january, 4th is always in week 1.
    const week1 = new Date(date.getFullYear(), 0, 4, 11, 0, 0, 0);
    const week1Monday = new Date(week1.getTime());
    // get the monday of the first week
    week1Monday.setDate(week1Monday.getDate() - (week1Monday.getDay() || 7) + 1);

    // check, if cal week is equal to last week of past year
    if (week1Monday.getTime() > date.getTime()) {
        if (week1Monday.getFullYear() === week1.getFullYear()) {
            return getWeek(new Date(week1Monday.getFullYear() - 1, 11, 31, 11));
        }
        return getWeek(new Date(week1Monday.getFullYear(), 11, 31, 11));
    }

    const firstOfYear  = new Date(date.getFullYear(), 0, 1, 11, 0, 0, 0);
    const lastOfYear  = new Date(date.getFullYear(), 11, 31, 11, 0, 0, 0);

    // check if current year is a leap year
    const isLeap = date.getFullYear() % 4 === 0;

    // check if current year has 53 weeks
    const has53 = !isLeap && (firstOfYear.getDay() === 4 && lastOfYear.getDay() === 4)  ||
        (isLeap && (firstOfYear.getDay() === 3 && lastOfYear.getDay() === 4 || firstOfYear.getDay() === 4 && lastOfYear.getDay() === 5));

    const dateMonday = new Date(date.getTime());
    dateMonday.setDate(dateMonday.getDate() - (dateMonday.getDay() || 7) + 1);

    // round is needed due to summer time / winter time difference ends up in non integer calculation
    const weekOffset= (dateMonday.getTime() - week1Monday.getTime()) / 1000 / 60 / 60 / 24;

    const result =  1 + Math.round(weekOffset / 7);
    if(result === 53 && !has53) {
        return 1;
    } else {
        return result;
    }
}
Scroll to Top