🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Weekday & DatePart in Excel — Datumsteile herausziehen, und warum Montag nicht 1 ist

|

VBA Weekday & DatePart in Excel — Datumsteile herausziehen, und warum Montag nicht 1 ist

TL;DRYear(d), Month(d), Day(d), Hour(t), Minute(t), Second(t) liefern je eine Ganzzahl aus einem Datum — einfach und eindeutig. Weekday(d) ist die Falle: Es liefert 1–7, aber die Nummerierung hängt von einem zweiten Argument ab, das standardmäßig vbSunday (1) ist, sodass Montag standardmäßig 2 ist, nicht 1. Übergeben Sie vbMonday (oder vergleichen Sie gegen die vb*-Konstanten), und die Wochenend-Logik hört auf, still falsch zu sein.

Sub PartsDemo()
    Dim d As Date: d = #2026-08-26#        ' ein Mittwoch
    Debug.Print Year(d), Month(d), Day(d)  ' 2026  8  26
    Debug.Print Weekday(d)                 ' 4  - Standard Sonntag=1, also Mi=4
    Debug.Print Weekday(d, vbMonday)       ' 3  - Montag=1, also Mi=3
    Debug.Print DatePart("ww", d)          ' 35 - Kalenderwoche (keine eigene Funktion)
End Sub

Teile herauszuziehen ist die Umkehrung von ein Datum aus Teilen bauen: Sie haben den Double und wollen das Jahr, den Monat, den Wochentag. Die meisten Funktionen sind genau so langweilig, wie sie sein sollten — Year, Month, Day lesen einfach die Zahl. Weekday ist die, die mehr Makros beendet hat, als sie sollte, ganz allein wegen einer Vorgabe, an die sich niemand erinnert.

Was Sie lernen

  • Die einfachen Extraktoren — Year, Month, Day, Hour, Minute, Second — je eine Ganzzahl
  • Warum Weekday für Montag standardmäßig 2 liefert, und das eine Argument, das es richtet
  • Wie Sie Wochenend- und Wochentagstests schreiben, die nicht heimlich falsch sind
  • DatePart — der allgemeine Extraktor, der an die Kalenderwoche und das Quartal kommt
  • Warum DatePart("ww", …)-Wochennummern an der Jahresgrenze um eins danebenliegen können (ISO 8601)
  • WeekdayName und MonthName liefern lokalisierte Namen — für die Anzeige, nicht zum Parsen

Die einfachen Extraktoren: je eine Ganzzahl

Year, Month und Day zerlegen ein Datum in seine Kalenderbestandteile; Hour, Minute und Second zerlegen den Uhrzeit-Nachkommateil. Jede liefert eine schlichte Integer, und es gibt nichts, worüber man stolpern könnte:

Dim d As Date: d = Now                 ' 2026-08-26 14:30:07
Debug.Print Year(d)      ' 2026
Debug.Print Month(d)     ' 8   (eine Zahl 1-12, nicht der Name)
Debug.Print Day(d)       ' 26
Debug.Print Hour(d)      ' 14  (24-Stunden)
Debug.Print Minute(d)    ' 30
Debug.Print Second(d)    ' 7

Month liefert 8, nicht "August" — es ist eine Zahl. Das sind die Bausteine, die Sie in DateSerial zurückfüttern, um verwandte Datumswerte zu konstruieren (Monatserster, gleicher Tag im nächsten Jahr und so weiter). Keine Überraschungen hier — genau deshalb erwischt Weekday die Leute auf dem falschen Fuß.

Warum Weekday für Montag 2 liefert

Weekday(date, [firstDayOfWeek]) liefert eine Zahl von 1 bis 7 — aber welcher Tag die 1 ist, legt das zweite Argument fest, und wenn Sie es weglassen, nimmt VBA vbSunday, also Sonntag = 1 und Montag = 2:

Weekday(#2026-08-24#)             ' 2  - jener Montag, weil Standard Sonntag=1
Weekday(#2026-08-24#, vbMonday)   ' 1  - jetzt Montag=1 ... Sonntag=7

Das ist der Paradebug der ganzen Familie. Code wie If Weekday(d) = 1 Then ' Monday ist falsch — 1 ist im Standardaufruf Sonntag — und Code wie If Weekday(d) = 6 Or Weekday(d) = 7 Then ' weekend hängt ganz von einer Annahme über den ersten Tag ab, die an der Aufrufstelle unsichtbar ist. Es gibt zwei robuste Fixes, und beide räumen das Raten aus:

' Fix 1 - den ersten Tag explizit setzen, dann ist Montag wirklich 1:
If Weekday(d, vbMonday) >= 6 Then MsgBox "weekend"   ' 6 = Sa, 7 = So

' Fix 2 - gegen die benannten Konstanten vergleichen, nie magische Zahlen:
If Weekday(d) = vbSaturday Or Weekday(d) = vbSunday Then MsgBox "weekend"

Die vb*-Konstanten (vbSunday, vbMonday, … vbSaturday) stimmen unabhängig vom Erster-Tag-Argument, weshalb der Vergleich gegen sie die sicherste Gewohnheit ist. Die Regel: Schreiben Sie nie eine nackte Zahl für einen Wochentag — übergeben Sie entweder vbMonday, damit die Nummerierung so ist, wie Sie sie erwarten, oder vergleichen Sie gegen eine vb*-Konstante.

DatePart: der allgemeine Extraktor

DatePart(interval, date, [firstDayOfWeek], [firstWeekOfYear]) ist die Schweizer-Taschenmesser-Variante: Es nimmt dieselben Intervallcodes wie DateAdd und DateDiff und zieht diese Einheit heraus. Für Jahr, Monat, Tag und Uhrzeit dupliziert es die eigenen Funktionen — aber es ist der einzige eingebaute Weg, an ein paar Teile zu kommen, die keine eigene Funktion haben:

DatePart("q", d)     ' Quartal des Jahres (1-4) - es gibt keine Quarter()-Funktion
DatePart("ww", d)    ' Kalenderwoche des Jahres (1-53)
DatePart("y", d)     ' Tag des Jahres (1-366) - hier meint y den Tag des Jahres
DatePart("m", d)     ' 8 - dasselbe wie Month(d)

Greifen Sie zu DatePart, wenn Sie das Quartal oder die Kalenderwoche brauchen, und nehmen Sie die schlichten Funktionen Year / Month / Day für die Alltagsteile, weil sie sich klarer lesen. Beachten Sie dieselbe Code-Falle wie bei DateAdd: "y" ist Tag-des-Jahres und "ww" ist Woche — sprechen Sie sie einmal laut aus.

Die Kalenderwochen-Falle an der Jahresgrenze

DatePart("ww", …) hat seine eigene Vorgabe, die Leute überrascht: Die erste Woche des Jahres und der erste Tag der Woche stehen beide standardmäßig auf einer US-Regel (vbSunday, vbFirstJan1), die nicht ISO 8601 ist — dem Standard, den der Großteil Europas und die meisten Geschäftskalender verwenden. So können die letzten Dezembertage und die ersten Januartage in einer Kalenderwoche landen, die Sie nicht erwartet haben:

DatePart("ww", #2026-12-31#)                          ' 53  (US-Standardregel)
DatePart("ww", #2026-12-31#, vbMonday, vbFirstFourDays) ' die ISO-Antwort

Wenn Ihre Kalenderwochen zählen — Lohnwochen, Sprint-Nummern, alles, was mit einem Kalender an der Wand übereinstimmen muss — übergeben Sie vbMonday als ersten Tag der Woche und vbFirstFourDays als Erste-Woche-Regel, um ISO 8601 zu treffen. Der klassische Bug „meine Kalenderwochen liegen rund um Neujahr um eins daneben" sind immer diese zwei Vorgaben.

WeekdayName und MonthName sind lokalisiert

Um eine Wochentags- oder Monatszahl in einen Namen zu verwandeln, nehmen Sie WeekdayName und MonthName. Beide liefern den Namen in der Sprache des Rechners, was sie ideal für die Anzeige macht und zum Fehler für alles, was Sie zurück-parsen:

WeekdayName(2)              ' "Monday" auf einer englischen Maschine, "Montag" auf einer deutschen
MonthName(8)               ' "August" / "August" / "aout" je nach Locale
WeekdayName(2, True)       ' abgekuerzt: "Mon"

Weil die Ausgabe der Locale des Nutzers folgt, vergleichen Sie sie nie mit einer festen englischen Zeichenkette und schreiben Sie sie nie in eine Datei, die ein anderes System liest — das ist ein Locale-Bug mit Ansage. Für eine stabile Beschriftung, die Sie kontrollieren, formatieren Sie stattdessen das Datum: Format(d, "dddd") gibt den vollen Wochentagsnamen und Format(d, "mmmm") den Monatsnamen, weiterhin Locale-bewusst, aber explizit, über Format. Nehmen Sie WeekdayName / MonthName für die Anzeige am Bildschirm; nehmen Sie Zahlen (Weekday, Month) für die Logik.

Das ehrliche Fazit: Die Teile sind leicht, die Vorgaben nicht

Teile aus einem Datum zu ziehen ist das am wenigsten mysteriöse an VBA-Datumswerten — mit einem Sternchen, das einen überproportionalen Anteil der Bugs verursacht:

  • Einfache Teile, einfache FunktionenYear, Month, Day, Hour, Minute, Second. Jede liefert eine Ganzzahl; Month ist eine Zahl, kein Name.
  • Weekday hat eine versteckte Vorgabe → sie ist vbSunday, also ist Montag 2. Übergeben Sie vbMonday, oder vergleichen Sie gegen vbSaturday / vbSunday — nie eine nackte Zahl.
  • DatePart für das, was keine Funktion hat → das Quartal ("q") und die Kalenderwoche ("ww"); treffen Sie ISO-Wochen mit vbMonday + vbFirstFourDays.
  • Namen sind lokalisiertWeekdayName / MonthName folgen der Rechnersprache; nehmen Sie sie zur Anzeige, nie zum Parsen.

Die eine Gewohnheit, die die meisten Bugs verhindert: Eine Wochentagszahl sollte nie ein Literal sein. Sagen Sie, welcher Tag der erste ist, oder benennen Sie den Tag, den Sie meinen.

Wie ExcelMaster hilft

Teil-Extraktions-Bugs sind subtil, weil der Code offensichtlich richtig aussieht: ein Wochenendfilter, der Weekday = 1 prüft, eine Kalenderwochen-Spalte, die jeden Januar mit dem Lohnkalender uneins ist, ein Bericht, der WeekdayName in eine Datei schreibt, die ein System in einer anderen Sprache dann nicht lesen kann. Jeder ist eine Vorgabe, an die sich niemand erinnert hat.

ExcelMaster schreibt die Extraktion, die auf Anhieb stimmt. Beschreiben Sie die Regel — „Wochenenden überspringen", „Zeilen nach Quartal gruppieren", „jede Zeile mit ihrer ISO-Woche beschriften" — und es nutzt Weekday(d, vbMonday) oder die vb*-Konstanten für Wochentags-Logik, DatePart mit den ISO-Argumenten für Kalenderwochen und hält Anzeigenamen getrennt von den Zahlen, nach denen Sie verzweigen. Sie beschreiben die Kalenderregel; es schreibt die Teil-Extraktion, die sich nicht auf eine versteckte Vorgabe verlässt.

Häufig gestellte Fragen

Warum liefert Weekday in VBA die falsche Tagesnummer?

Weil Weekday die Woche ab seinem zweiten Argument nummeriert, das standardmäßig vbSunday ist — also ist Sonntag 1 und Montag 2. Wenn Sie annahmen, Montag sei 1, liegt jedes Ergebnis um eins daneben. Übergeben Sie den ersten Tag explizit, Weekday(d, vbMonday), dann ist Montag 1 bis Sonntag 7, oder vergleichen Sie das Ergebnis gegen die benannten Konstanten vbSaturday und vbSunday statt gegen fest verdrahtete Zahlen.

Wie prüfe ich in VBA, ob ein Datum ein Wochenende ist?

Nehmen Sie die Konstanten, damit die Erster-Tag-Vorgabe Sie nicht beißen kann: If Weekday(d) = vbSaturday Or Weekday(d) = vbSunday Then …. Die vb*-Konstanten stimmen, egal welches Erster-Tag-der-Woche-Argument im Spiel ist. Alternativ behandelt Weekday(d, vbMonday) >= 6 die 6 (Samstag) und 7 (Sonntag) als Wochenende — stellen Sie nur sicher, dass Sie vbMonday übergeben haben.

Wie bekomme ich in VBA das Quartal oder die Kalenderwoche eines Datums?

Nehmen Sie DatePart, denn es gibt keine eigene Quarter- oder Week-Funktion. DatePart("q", d) liefert das Quartal 1–4, und DatePart("ww", d) liefert die Kalenderwoche. Für ISO-8601-Kalenderwochen übergeben Sie die zusätzlichen Argumente: DatePart("ww", d, vbMonday, vbFirstFourDays), sonst kann die Woche rund um Neujahr um eins danebenliegen.

Was ist der Unterschied zwischen Month und MonthName in VBA?

Month(d) liefert den Monat als Zahl (1–12) für den Einsatz in der Logik; MonthName(n) verwandelt eine Monatszahl in ihren Namen als Text (MonthName(8) ergibt „August"). MonthName folgt der Sprache des Rechners, nehmen Sie es also nur für die Anzeige — für Verzweigungen oder Vergleiche nehmen Sie die Zahl aus Month.

Liefert WeekdayName in VBA englische Namen?

Nur auf einer englischsprachigen Maschine. WeekdayName und MonthName liefern Namen in der Locale des Systems, sodass derselbe Code auf verschiedenen Rechnern „Monday" oder „Montag" oder „lundi" erzeugt. Vergleichen Sie ihre Ausgabe nie mit einer festen englischen Zeichenkette; für eine kontrollierte Beschriftung nehmen Sie Format(d, "dddd"), und für die Logik nehmen Sie das numerische Weekday.

Getestet in

Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 26.08.2026.

Verwandte Anleitungen: VBA DateAdd & DateDiff · VBA Now, Date & Time · VBA Format · VBA CStr, CDate & Val · VBA For Loop