n8n selbst hosten mit Docker Compose: Komplettanleitung für deutsche Server
So installieren Sie n8n mit Docker Compose: Postgres statt SQLite, .env, Volumes und Updates Schritt für Schritt.
Luxon in n8n: deutsche Datumsformate mit toFormat und setLocale erzeugen und typische Zeitzonen-Fallen in Ausdrücken vermeiden.
n8n verarbeitet Datum und Uhrzeit intern über die JavaScript-Bibliothek Luxon und nicht über das native Date-Objekt von JavaScript. Das merken Sie meistens erst dann, wenn ein Workflow ein Datum ausgibt, das eine Stunde daneben liegt, ein Monatsname auf Englisch statt auf Deutsch erscheint oder ein Beleg am Monatsende plötzlich auf dem falschen Tag landet. Sobald Sie verstehen, wie Luxon Zeitzone, Sprache und Format sauber trennt, lassen sich genau diese Fehler gezielt vermeiden, und Sie behalten die Kontrolle darüber, welches Datum am Ende wirklich in Rechnung, CRM oder Tabelle steht.
Dieser Artikel konzentriert sich bewusst auf die Formatierung von Datum und Uhrzeit in Ausdrücken und im Date & Time Node, nicht auf die Zeitzonen-Logik des Schedule Triggers oder von Cron-Ausdrücken. Das ist ein eigenes Thema mit eigenen Stolperfallen, das einen separaten Blick verdient.
Reines JavaScript kennt kein eingebautes Konzept für Zeitzonen oder Sprachformate, die über das Grundlegendste hinausgehen. Luxon füllt genau diese Lücke: Jedes Datum, das n8n intern erzeugt, etwa über $now oder $today, ist ein Luxon-DateTime-Objekt mit eigener Zeitzone, eigener Sprache (Locale) und eigenen Methoden zum Rechnen, Vergleichen und Formatieren. Laut der offiziellen Dokumentation zur Arbeit mit Datum und Uhrzeit in n8n werden Datumswerte zwischen Nodes als Strings weitergereicht und müssen für Berechnungen oder Formatierungen erst wieder mit Luxon-Funktionen geparst werden. Das native JavaScript-Date() respektiert die in n8n eingestellte Zeitzone nicht, weshalb die Dokumentation ausdrücklich empfiehlt, für alles rund um Datum und Uhrzeit bei Luxon zu bleiben.
Für die eigentliche Formatierung stehen in Ausdrücken mehrere Wege offen, die unterschiedlich gut für deutsche Anforderungen geeignet sind:
.toFormat(fmt): die native Luxon-Methode, mit der Sie ein Format über feste Tokens selbst zusammenbauen, etwa dd.MM.yyyy. Sie funktioniert überall, auch im Code-Node..toLocaleString(opts): liefert ein lokalisiertes, also sprachabhängiges Format. Ohne gesetzte Locale orientiert sich das Ergebnis an der Standardsprache der n8n-Instanz, was in der Praxis oft Englisch bedeutet.format(): eine n8n-eigene Erweiterung der Ausdruckssprache für Datumsformatierung, die laut der DateTime-Ausdrucksreferenz im Code-Node nicht verfügbar ist. Dort greifen Sie stattdessen auf das native .toFormat() zurück.MM/DD/YYYY oder YYYY-MM-DD mit, dazu eine Option für ein eigenes Format. Laut Dokumentation zum Date & Time Node unterstützt n8n dafür alle Formate, die auch Luxon selbst kennt, wobei die Tokens groß-/kleinschreibungssensitiv sind.Für ein rein numerisches deutsches Datum reicht meistens .toFormat() mit einem festen Token-Muster, während .toLocaleString() und .setLocale() dann wichtig werden, sobald ausgeschriebene Monats- oder Wochentagsnamen auf Deutsch erscheinen sollen.
Für die klassische deutsche Schreibweise TT.MM.JJJJ reicht ein fester Ausdruck ohne Locale-Abhängigkeit:
{{$now.toFormat('dd.MM.yyyy')}} ergibt zum Beispiel 20.07.2026.{{$now.toFormat('dd.MM.yyyy HH:mm')}} ergänzt die Uhrzeit im 24-Stunden-Format.Sobald ausgeschriebene Namen ins Spiel kommen, etwa für eine Rechnung oder einen Serienbrief, brauchen Sie zusätzlich die deutsche Locale, weil sonst der Monatsname auf Englisch ausgegeben wird:
{{$now.setLocale('de-DE').toLocaleString({month: 'long', day: 'numeric', year: 'numeric'})}} liefert ein Ergebnis wie 20. Juli 2026.{{$now.setLocale('de-DE').monthLong}} gibt direkt den ausgeschriebenen Monatsnamen zurück, etwa Juli.Wichtig dabei: .setLocale() ändert ausschließlich die Sprache der Ausgabe, nicht die Zeitzone. Beide Einstellungen müssen Sie getrennt voneinander setzen, sonst bekommen Sie zwar ein deutsches Wort für den Monat, aber unter Umständen trotzdem die falsche Uhrzeit.
Die meisten Fehler entstehen nicht beim Format selbst, sondern bei der Zeitzone, in der formatiert wird. Ein paar Fallen, die in der Praxis immer wieder auftauchen:
America/New York, auf n8n Cloud fällt das System auf GMT zurück. $now und $today orientieren sich an dieser Instanz-Zeitzone, sofern kein Workflow-eigenes Setting oder keine GENERIC_TIMEZONE-Umgebungsvariable etwas anderes vorgibt. Wer das übersieht, bekommt Zeitstempel, die um mehrere Stunden von der deutschen Uhrzeit abweichen..setZone(): .toFormat() und .toLocaleString() geben immer die Uhrzeit in der Zeitzone aus, die das DateTime-Objekt gerade hat, nicht automatisch Europe/Berlin. Kommt ein Datum aus einer API in UTC oder in einer fremden Zeitzone, sollten Sie es zuerst mit .setZone('Europe/Berlin') umrechnen und erst danach formatieren, sonst landet ein Beleg, der um 23:30 Uhr deutscher Zeit erstellt wurde, in der Auswertung plötzlich auf dem Folgetag..plus({days: n}) über einen solchen Wechsel hinweg und formatieren danach die Uhrzeit, kann sich der Zeitanteil um eine Stunde verschieben, obwohl der Kalendertag stimmt. Für reine Datums-ohne-Uhrzeit-Vergleiche ist das meist unkritisch, für zeitkritische Prozesse sollten Sie es einplanen..toISO() mit Offset weiterreichen: Der ISO-String von Luxon enthält standardmäßig den Zeitzonen-Offset, etwa +02:00. Systeme, die stattdessen reines UTC oder einen offset-losen String erwarten, interpretieren diesen Wert sonst falsch weiter. Prüfen Sie im Zielsystem, welches Format tatsächlich erwartet wird, bevor Sie das Ergebnis blind übergeben.Ein typischer Fall aus der Praxis: Ein Workflow holt ein Belegdatum aus einer API, die UTC-Zeitstempel liefert, und soll daraus ein deutsches Rechnungsdatum erzeugen. Der Ausdruck dafür sieht kombiniert so aus:
{{ $json.createdAt.toDateTime().setZone('Europe/Berlin').setLocale('de-DE').toFormat('dd.MM.yyyy') }}Die Reihenfolge ist dabei kein Zufall: Zuerst wird der native JavaScript-Zeitstempel in ein Luxon-DateTime umgewandelt, dann in die richtige Zeitzone verschoben, danach die Sprache gesetzt und erst zum Schluss formatiert. Vertauschen Sie Zeitzonen- und Formatierungsschritt, bekommen Sie zwar ein korrekt aussehendes deutsches Datum, aber möglicherweise für den falschen Kalendertag.
.toFormat() und .toLocaleString()?.toFormat() folgt einem festen, von Ihnen selbst definierten Token-Muster wie dd.MM.yyyy und liefert unabhängig von der Locale immer dasselbe Layout. .toLocaleString() orientiert sich dagegen an der gesetzten Sprache und passt Reihenfolge sowie Schreibweise automatisch an, was besonders bei ausgeschriebenen Monats- oder Wochentagsnamen den Unterschied macht.
Ohne ein explizites .setLocale('de-DE') verwendet Luxon die Standardsprache der n8n-Instanz, die häufig auf Englisch steht. Die Zeitzone der Instanz und ihre Sprache sind zwei getrennte Einstellungen, weshalb ein korrekt eingestelltes Europe/Berlin allein noch keinen deutschen Monatsnamen garantiert.
Immer dann, wenn ein Datum aus einer externen Quelle wie einer API, einer Datenbank oder einem Formular stammt, ja. Solche Werte liegen oft in UTC oder in einer fremden Zeitzone vor, und nur $now beziehungsweise $today folgen automatisch der in n8n konfigurierten Instanz- oder Workflow-Zeitzone.
Nein, dort gelten eigene Regeln für die Ausführungszeit selbst, nicht für die Formatierung von Datumswerten in Ausdrücken. Dieser Artikel behandelt ausschließlich, wie ein bereits vorhandenes Datum innerhalb eines Workflows korrekt formatiert wird.
n8n unterstützt laut Dokumentation zum Date & Time Node sämtliche Tokens, die auch Luxon selbst kennt, wobei Groß- und Kleinschreibung jeweils eine eigene Bedeutung hat. Für den vollständigen Überblick über alle verfügbaren Tokens lohnt sich ein Blick in die verlinkte Luxon-Formatierungsreferenz direkt aus der n8n-Dokumentation heraus.
Gründer von NordFlux. Sieben Jahre Erfahrung von Web und SEO bis zur Automatisierung im Konzern-Maßstab, heute pragmatisch für den Mittelstand und mit deutscher Datenhoheit.
Zertifizierungen
So installieren Sie n8n mit Docker Compose: Postgres statt SQLite, .env, Volumes und Updates Schritt für Schritt.
n8n läuft standardmäßig in America/New_York statt Europe/Berlin. So setzen Sie GENERIC_TIMEZONE und die Workflow-Zeitzone richtig.
Falsch formatierte Rechnungsdaten oder verschobene Zeitstempel durch Zeitzonen-Fallen kosten im Ernstfall Vertrauen bei Kunden und Behörden. NordFlux entwickelt und prüft Ihre n8n-Workflows so, dass Datums- und Zeitlogik auch bei internationalen Datenquellen korrekt bleibt. Im ersten Gespräch schauen wir uns Ihre kritischen Ausdrücke gemeinsam an.