date-fns & Day.js mit Claude Code: Datums-Manipulation 2026
Moment.js ist tot — date-fns und Day.js sind die modernen Alternativen. Claude Code kennt beide Libraries: Formatierung, Zeitzone-Handling, Kalender-Logik, i18n und die nativen Intl-APIs als Zero-Dependency-Alternative.
date-fns vs Day.js vs Intl: Wann was nutzen?
| Kriterium | date-fns | Day.js | Intl (nativ) |
|---|---|---|---|
| Bundle-Size | Tree-shakeable (~2kb/fn) | ~2kb Basis + Plugins | 0kb (Browser-nativ) |
| API-Stil | Funktional (pure functions) | Chainable (moment-kompatibel) | Low-Level |
| TypeScript | Vollständig typisiert | Gut (mit @types/dayjs) | Vollständig (eingebaut) |
| Zeitzone-Support | date-fns-tz Plugin | dayjs/plugin/timezone | Temporal API (neu) |
| i18n | locale-Objekte | dayjs/locale/de | Intl.DateTimeFormat |
| Moment.js Migration | Unterschiedliche API | Fast identisch | Manuelle Migration |
date-fns: Funktionale Datums-Operationen
date-fnsFormatierung und Manipulation
# Prompt: "Datums-Operationen für unser Event-Booking-System"
import {
format, parseISO, addDays, subMonths,
startOfWeek, endOfWeek, eachDayOfInterval,
isWithinInterval, differenceInDays, isBefore,
isAfter, formatDistanceToNow, setHours
} from 'date-fns';
import { de } from 'date-fns/locale';
// Formatierung mit Locale:
const today = new Date();
format(today, 'dd. MMMM yyyy', { locale: de }); // "5. Mai 2026"
format(today, 'EEEE, dd.MM.yyyy', { locale: de }); // "Dienstag, 05.05.2026"
format(today, 'HH:mm'); // "14:30"
// ISO-String parsen (NIEMALS new Date(string) für ISO!):
const eventDate = parseISO('2026-06-15T10:00:00Z');
// Manipulation:
const nextWeek = addDays(today, 7);
const lastMonth = subMonths(today, 1);
const startOfThisWeek = startOfWeek(today, { weekStartsOn: 1 }); // Montag
// Kalender-Woche generieren:
const weekDays = eachDayOfInterval({
start: startOfWeek(today, { weekStartsOn: 1 }),
end: endOfWeek(today, { weekStartsOn: 1 }),
});
// Verfügbarkeit prüfen:
const isAvailable = isWithinInterval(eventDate, {
start: today,
end: addDays(today, 30),
});
// Relative Zeit:
formatDistanceToNow(eventDate, { locale: de, addSuffix: true });
// "in 40 Tagen"
// Differenz in Tagen:
const daysUntilEvent = differenceInDays(eventDate, today); // 41
date-fns-tz: Zeitzone-Handling
TimezoneUTC und lokale Zeitzonen korrekt
// Prompt: "Booking-System mit Zeitzone-Support — Berlin + New York"
import { format, parseISO } from 'date-fns';
import { toZonedTime, fromZonedTime, formatInTimeZone } from 'date-fns-tz';
const berlinTZ = 'Europe/Berlin';
const nyTZ = 'America/New_York';
// UTC → Berlin-Zeit konvertieren:
const utcDate = parseISO('2026-06-15T10:00:00Z');
const berlinDate = toZonedTime(utcDate, berlinTZ);
format(berlinDate, 'HH:mm zzz'); // "12:00 CEST"
// Berlin-Lokale Zeit → UTC für DB-Speicherung:
const localInput = '2026-06-15 14:00'; // User gibt Berliner Zeit ein
const utcForDB = fromZonedTime(localInput, berlinTZ);
// → "2026-06-15T12:00:00.000Z" für DB
// Direkt in Zeitzone formatieren:
formatInTimeZone(utcDate, berlinTZ, 'dd.MM.yyyy HH:mm zzz');
// "15.06.2026 12:00 CEST"
formatInTimeZone(utcDate, nyTZ, 'dd.MM.yyyy HH:mm zzz');
// "15.06.2026 06:00 EDT"
// Browser-Zeitzone des Users ermitteln:
const userTZ = Intl.DateTimeFormat().resolvedOptions().timeZone;
// → "Europe/Berlin" (je nach Browser-Einstellung)
Goldene Regel: Datums-Werte IMMER in UTC in der Datenbank speichern. Nur für die Anzeige in lokale Zeitzone konvertieren. Niemals lokale Zeiten in der DB speichern — damit werden Daylight-Saving-Time-Bugs vermieden.
Day.js: Moment.js-kompatibler Ersatz
Day.jsMigration von Moment.js
# Prompt: "Migriere unsere Moment.js-Nutzung zu Day.js"
// Moment.js (deprecated, 230kb ungzipped):
moment().format('DD. MMMM YYYY');
moment().add(7, 'days').startOf('week');
// Day.js — fast identische API, 2kb:
import dayjs from 'dayjs';
import 'dayjs/locale/de';
import relativeTime from 'dayjs/plugin/relativeTime';
import timezone from 'dayjs/plugin/timezone';
import utc from 'dayjs/plugin/utc';
import isBetween from 'dayjs/plugin/isBetween';
dayjs.extend(relativeTime);
dayjs.extend(timezone);
dayjs.extend(utc);
dayjs.extend(isBetween);
dayjs.locale('de');
// Nutzung (fast 1:1 zu Moment.js):
dayjs().format('DD. MMMM YYYY'); // "05. Mai 2026"
dayjs().add(7, 'day').startOf('week').format(); // ISO-String
dayjs('2026-06-15').fromNow(); // "in 41 Tagen"
dayjs().tz('America/New_York').format('HH:mm'); // New York Zeit
dayjs('2026-06-01').isBetween('2026-05-01', '2026-07-01'); // true
Native Intl-APIs: Zero Dependencies
// Prompt: "Datum formatieren ohne externe Library — nur Browser-APIs"
// Intl.DateTimeFormat — vollständig lokalisiert:
const formatter = new Intl.DateTimeFormat('de-DE', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
timeZone: 'Europe/Berlin',
});
formatter.format(new Date());
// "Dienstag, 5. Mai 2026 um 14:30"
// Relative Zeit (kein date-fns nötig!):
const rtf = new Intl.RelativeTimeFormat('de', { numeric: 'auto' });
rtf.format(-3, 'day'); // "vorgestern"
rtf.format(2, 'week'); // "in 2 Wochen"
rtf.format(-1, 'month'); // "letzten Monat"
// Kalender-Woche (ISO 8601):
function getWeekNumber(date: Date): number {
const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
return Math.ceil((((d.getTime() - yearStart.getTime()) / 86400000) + 1) / 7);
}
Wann welche Library: Für einfache Formatierung →
Intl (Zero Dependency). Für Moment.js-Migration → Day.js (API-kompatibel). Für komplexe Kalender-Logik (Buchungssysteme, Abonnements, Arbeitstage) → date-fns (Tree-shakeable, funktional). Claude Code wählt die passende Library basierend auf den Anforderungen.Datums-Modul im Kurs
Im Claude Code Mastery Kurs: vollständiges Datums-Modul mit date-fns, Day.js, Zeitzone-Handling, Kalender-Implementierungen, Moment.js-Migration und nativen Intl-APIs — inkl. Booking-System-Beispiel.
14 Tage kostenlos testen →