Tutorial

Vollständiger Leitfaden für JavaScript-Zeitstempel

Einführung

JavaScript stellt das Date-Objekt für die Arbeit mit Datums- und Zeitstempeln bereit. Für die Webentwicklung, Datenverarbeitung und zeitbasierte Anwendungen ist es wichtig zu verstehen, wie Zeitstempel in JavaScript richtig verwendet werden. Dieser Leitfaden behandelt die Grundlagen von Zeitstempeln, Konvertierungen, die Handhabung von Zeitzonen und Best Practices.

JavaScript-Zeitstempel verstehen

Unix-Zeitstempel in JavaScript

JavaScript verwendet Unix-Zeitstempel in Millisekunden seit dem 1. Januar 1970, 00:00:00 UTC (der Unix-Epoche):

JavaScript Timestamp = Milliseconds since 1970-01-01 00:00:00 UTC

Example: 1704624000000
  = 1704624000 seconds since epoch
  = January 8, 2024, 12:00:00 PM UTC

Wichtig: JavaScript verwendet Millisekunden, während viele andere Systeme Sekunden verwenden. Überprüfen Sie beim Umrechnen immer die Einheiten.

Aktueller Zeitstempel

// Current timestamp in milliseconds
const nowMs = Date.now();
console.log(nowMs);  // e.g., 1704624000000

// Alternative method
const nowMs2 = new Date().getTime();
console.log(nowMs2);  // Same as Date.now()

// Convert to seconds
const nowSec = Math.floor(Date.now() / 1000);
console.log(nowSec);  // e.g., 1704624000

Termine erstellen

Datumsobjekte erstellen

Vom Zeitstempel

// Create from milliseconds timestamp
const dateFromMs = new Date(1704624000000);
console.log(dateFromMs.toISOString());  // "2024-01-08T12:00:00.000Z"

// Create from seconds timestamp (multiply by 1000)
const dateFromSec = new Date(1704624000 * 1000);
console.log(dateFromSec.toISOString());  // "2024-01-08T12:00:00.000Z"

Aus Datumskomponenten

// Create from year, month, day (months are 0-indexed!)
const date1 = new Date(2024, 0, 8);  // January 8, 2024
console.log(date1.toISOString());  // "2024-01-08T00:00:00.000Z"

// Create with time
const date2 = new Date(2024, 0, 8, 14, 30, 0);
console.log(date2.toISOString());  // "2024-01-08T14:30:00.000Z"

// Create from string (ISO 8601 recommended)
const date3 = new Date('2024-01-08T14:30:00.000Z');
console.log(date3.toISOString());  // "2024-01-08T14:30:00.000Z"

Häufiger Fehler: JavaScript-Monate sind 0-indiziert (0 = Januar, 11 = Dezember)!

Aktuelles Datum und Uhrzeit

const now = new Date();

console.log(now.toISOString());        // "2024-01-08T12:34:56.789Z"
console.log(now.toString());           // "Mon Jan 08 2024 07:34:56 GMT-0500"
console.log(now.toDateString());      // "Mon Jan 08 2024"
console.log(now.toTimeString());      // "07:34:56 GMT-0500"
console.log(now.toLocaleString());     // "1/8/2024, 7:34:56 AM"

Datumskomponenten abrufen

Datumsteile extrahieren

const date = new Date(2024, 0, 8, 14, 30, 45, 123);

// Get components
console.log(date.getFullYear());      // 2024
console.log(date.getMonth());        // 0 (January - 0-indexed!)
console.log(date.getDate());         // 8 (day of month)
console.log(date.getHours());        // 14 (hour 0-23)
console.log(date.getMinutes());      // 30 (minutes 0-59)
console.log(date.getSeconds());      // 45 (seconds 0-59)
console.log(date.getMilliseconds()); // 123 (milliseconds 0-999)

// Get day of week (0 = Sunday, 6 = Saturday)
console.log(date.getDay());          // 1 (Monday)

// Get UTC components
console.log(date.getUTCFullYear()); // 2024
console.log(date.getUTCHours());   // 19 (if local is 14:30)

Relative Zeitkomponenten

const date = new Date(2024, 0, 8);

// Get timezone offset (in minutes)
const offset = date.getTimezoneOffset();
console.log(offset);  // e.g., -300 (UTC-5 = -5 * 60)

// Get timestamp
const timestamp = date.getTime();
console.log(timestamp);  // e.g., 1704672000000 (milliseconds)

// Get ISO 8601 string
const isoString = date.toISOString();
console.log(isoString);  // "2024-01-08T00:00:00.000Z"

Datumskomponenten festlegen

Daten ändern

const date = new Date(2024, 0, 8);

// Set components (returns timestamp)
date.setFullYear(2025);
date.setMonth(11);      // December
date.setDate(25);
date.setHours(18);
date.setMinutes(30);
date.setSeconds(45);
date.setMilliseconds(0);

console.log(date.toISOString());  // "2025-12-25T18:30:45.000Z"

// Set UTC components
date.setUTCFullYear(2025);
date.setUTCHours(12);

Wichtig: Set-Methoden geben den Zeitstempel zurück, nicht das Date-Objekt. Sorgfältig verketten:

// Correct: Use same date object
const date = new Date(2024, 0, 8);
date.setDate(15);
date.setMonth(5);  // June 15, 2024

// WRONG: Creates new date, loses changes
const date = new Date(2024, 0, 8);
new Date(date).setDate(15);  // Original date unchanged!

Datumsarithmetik

Zeit addieren und subtrahieren

const date = new Date(2024, 0, 8);

// Add 7 days
date.setDate(date.getDate() + 7);
console.log(date.toISOString());  // "2024-01-15T00:00:00.000Z"

// Add 3 hours (3600 * 1000 ms)
date.setTime(date.getTime() + (3 * 3600 * 1000));
console.log(date.toISOString());  // "2024-01-15T03:00:00.000Z"

// Subtract 1 month
date.setMonth(date.getMonth() - 1);
console.log(date.toISOString());  // "2023-12-15T03:00:00.000Z"

// Add 1 year
date.setFullYear(date.getFullYear() + 1);
console.log(date.toISOString());  // "2024-12-15T03:00:00.000Z"

Best Practice: Verwenden Sie Zeitstempelarithmetik für Präzision:

> // Add 1 hour in milliseconds (60 * 60 * 1000)
> const oneHour = 60 * 60 * 1000;
> const newDate = new Date(date.getTime() + oneHour);
>

Zeitunterschiede

const date1 = new Date(2024, 0, 8);
const date2 = new Date(2024, 0, 15);

// Difference in milliseconds
const diffMs = date2 - date1;
console.log(diffMs);  // 604800000 (7 days in ms)

// Convert to seconds, minutes, hours, days
const diffSec = Math.floor(diffMs / 1000);
const diffMin = Math.floor(diffMs / (1000 * 60));
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));

console.log(`${diffDays} days`);  // "7 days"
console.log(`${diffHours} hours`);  // "168 hours"

Datumsangaben formatieren

Integrierte Formatierung

toLocaleString-Familie

const date = new Date(2024, 0, 8, 14, 30, 45);

// Locale-specific formats
console.log(date.toLocaleDateString());      // "1/8/2024"
console.log(date.toLocaleTimeString());      // "2:30:45 PM"
console.log(date.toLocaleString());         // "1/8/2024, 2:30:45 PM"

// With locale options
console.log(date.toLocaleDateString('en-US', {
  weekday: 'long',
  year: 'numeric',
  month: 'long',
  day: 'numeric'
}));
// "Monday, January 8, 2024"

console.log(date.toLocaleDateString('zh-CN', {
  year: 'numeric',
  month: 'long',
  day: 'numeric'
}));
// "2024年1月8日"

Internationale Formate

const date = new Date(2024, 0, 8);

// ISO 8601 (always UTC)
console.log(date.toISOString());  // "2024-01-08T00:00:00.000Z"

// UTC string
console.log(date.toUTCString());  // "Sun, 07 Jan 2024 00:00:00 GMT"

// Date string (local time)
console.log(date.toString());  // "Mon Jan 08 2024 00:00:00 GMT-0500"

Best Practice: Verwenden Sie immer toISOString() für API-Aufrufe und Datenbankspeicherung, um Zeitzonenprobleme zu vermeiden.

Benutzerdefinierte Formatierung

// Manual formatting (use Intl.DateTimeFormat for i18n)
function formatDate(date) {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  const seconds = String(date.getSeconds()).padStart(2, '0');

  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

console.log(formatDate(new Date(2024, 0, 8, 14, 30, 45)));
// "2024-01-08 14:30:45"

Empfehlung: Verwenden Sie Bibliotheken wie date-fns, luxon oder day.js für komplexe Formatierungen anstelle einer manuellen Formatierung.

Zeitzonenbehandlung

Arbeiten mit Zeitzonen

Zeitzoneninformationen abrufen

const date = new Date();

// Get timezone offset (in minutes)
const offset = date.getTimezoneOffset();
console.log(offset);  // e.g., -300 (UTC-5) or 300 (UTC+5)

// Convert offset to hours
const offsetHours = offset / 60;
console.log(offsetHours);  // -5 or 5

// Get timezone name (browser-specific)
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(timezone);  // e.g., "America/New_York"

Konvertieren zwischen Zeitzonen

const date = new Date(2024, 0, 8, 14, 30, 0);

// Convert to different timezone using toLocaleString
const nyTime = date.toLocaleString('en-US', {
  timeZone: 'America/New_York',
  timeZoneName: 'short'
});
console.log(nyTime);  // "1/8/2024, 9:30:00 AM EST"

const tokyoTime = date.toLocaleString('en-US', {
  timeZone: 'Asia/Tokyo'
});
console.log(tokyoTime);  // "1/8/2024, 11:30:00 PM"

// Extract time components in specific timezone
const tokyoDate = new Date(date.toLocaleString('en-US', {
  timeZone: 'Asia/Tokyo'
}));
console.log(tokyoDate.getHours());  // 23 (11 PM)

Best Practice: Arbeiten Sie intern immer mit UTC und konvertieren Sie nur zur Anzeige in die lokale Zeitzone.

UTC vs. Ortszeit

const date = new Date(2024, 0, 8, 14, 30, 0);

// Local time methods
console.log(date.getHours());     // Local hour (e.g., 14 for EST)
console.log(date.getTime());    // Timestamp (same regardless of timezone)

// UTC methods
console.log(date.getUTCHours()); // UTC hour (e.g., 19 for EST)
console.log(date.getUTCDate());  // UTC day of month

Parsing-Daten

Datumszeichenfolgen analysieren

Verwenden des Datumskonstruktors

// ISO 8601 (recommended)
const isoDate = new Date('2024-01-08T14:30:00.000Z');
console.log(isoDate.toISOString());  // "2024-01-08T14:30:00.000Z"

// Short date format (browser-dependent, avoid!)
const shortDate = new Date('01/08/2024');
console.log(shortDate);  // May be Jan 8 or Aug 8 depending on locale

// RFC 2822 format
const rfcDate = new Date('Mon, 08 Jan 2024 14:30:00 GMT');
console.log(rfcDate.toISOString());  // "2024-01-08T14:30:00.000Z"

Problem: Die Datumsanalyse ist in allen Browsern und Gebietsschemas inkonsistent.

Manuelles Parsen

// Parse ISO 8601 string manually
function parseISOString(isoString) {
  const date = new Date(isoString);
  if (isNaN(date.getTime())) {
    throw new Error('Invalid date string');
  }
  return date;
}

// Parse custom format (YYYY-MM-DD)
function parseCustomDate(dateString) {
  const [year, month, day] = dateString.split('-').map(Number);
  return new Date(year, month - 1, day);  // months are 0-indexed
}

console.log(parseCustomDate('2024-01-08').toISOString());
// "2024-01-08T00:00:00.000Z"

Empfehlung: Verwenden Sie Bibliotheken wie date-fns/parse oder luxon/DateTime.fromISO für zuverlässiges Parsen.

Validierung von Daten

// Check if date is valid
function isValidDate(date) {
  return date instanceof Date && !isNaN(date.getTime());
}

// Examples
const validDate = new Date(2024, 0, 8);
const invalidDate = new Date('invalid');

console.log(isValidDate(validDate));    // true
console.log(isValidDate(invalidDate));  // false
console.log(isNaN(invalidDate.getTime()));  // true (NaN)

Häufige Fallstricke

Monatsindizierung

// Common mistake: Using 1-12 for months
const date = new Date(2024, 12, 8);  // January 2025!
console.log(date.toISOString());  // "2025-01-08T00:00:00.000Z"

// Correct: Use 0-11 for months
const date = new Date(2024, 11, 8);  // December 2024
console.log(date.toISOString());  // "2024-12-08T00:00:00.000Z"

Zeitzonenverwirrung

const date = new Date(2024, 0, 8, 0, 0, 0);

// These produce different values!
console.log(date.getTime());     // 1704672000000 (same)
console.log(date.toString());     // "Mon Jan 08 2024 00:00:00 GMT-0500"
console.log(date.toISOString()); // "2024-01-08T05:00:00.000Z"

// Midnight EST = 5:00 AM UTC

Problem: Beim Erstellen von Daten ohne Zeitzoneninformationen wird die Ortszeit angenommen.

Inkonsistenzen beim Parsen von Zeichenfolgen

// Different browsers may parse differently
const date1 = new Date('2024-01-08');      // Might be Jan 8 or Jan 1
const date2 = new Date('2024/01/08');      // Might be parsed differently
const date3 = new Date('01-08-2024');      // Very ambiguous!

// Always use ISO 8601
const date = new Date('2024-01-08T00:00:00Z');
console.log(date.toISOString());  // Consistent across all browsers

Mathe-Überlauf

const date = new Date(2024, 0, 31);

// Add 2 months to Jan 31
date.setMonth(date.getMonth() + 2);
console.log(date.toISOString());  // "2024-03-31T00:00:00.000Z" ✓

// Add 1 month to Jan 31 (February doesn't have 31!)
date.setMonth(date.getMonth() + 1);
console.log(date.toISOString());  // "2024-03-02T00:00:00.000Z" ✓

// JavaScript auto-adjusts overflow

Vorteil: JavaScript verarbeitet automatisch einen Datumsüberlauf (31. Februar → 2. oder 3. März, je nach Schaltjahr).

Best Practices

Leistung

Vermeiden Sie häufige Datumserstellung

// BAD: Create new Date in loop
for (let i = 0; i < 1000; i++) {
  const now = new Date();
  // ... operations
}

// GOOD: Create once, reuse
const now = new Date();
const timestamp = now.getTime();
for (let i = 0; i < 1000; i++) {
  // ... operations with timestamp
}

Zeitstempel für Vergleiche verwenden

const date1 = new Date(2024, 0, 8);
const date2 = new Date(2024, 0, 15);

// BAD: Compare Date objects (slow)
if (date1 < date2) { }

// GOOD: Compare timestamps (fast)
if (date1.getTime() < date2.getTime()) { }

// Even better: Use timestamps directly
const ts1 = date1.getTime();
const ts2 = date2.getTime();
if (ts1 < ts2) { }

Cache-Zeitzonenversatz

// Cache timezone offset (doesn't change during runtime)
const TZ_OFFSET = new Date().getTimezoneOffset() * 60 * 1000;

// Use in conversions
function toLocalTime(timestamp) {
  return new Date(timestamp + TZ_OFFSET);
}

console.log(toLocalTime(Date.now()));

Datenintegrität

// Validate before operations
function safeDateOperation(callback) {
  try {
    const result = callback();
    if (isNaN(result.getTime())) {
      throw new Error('Invalid date result');
    }
    return result;
  } catch (error) {
    console.error('Date operation failed:', error);
    return new Date();  // Return current time as fallback
  }
}

// Usage
const result = safeDateOperation(() => {
  return new Date(invalidInput);
});

Best Practices für die Speicherung

// Store as ISO 8601 string
function serializeDate(date) {
  return date.toISOString();
}

// Deserialize from ISO 8601
function deserializeDate(isoString) {
  return new Date(isoString);
}

// Usage in JSON
const data = {
  timestamp: Date.now(),
  isoDate: new Date().toISOString(),
  userCreated: serializeDate(new Date())
};

// Parse from API
const createdDate = deserializeDate(apiResponse.userCreated);

Gemeinsame Operationen

Utility-Funktionen

Beginn/Ende des Tages

function startOfDay(date) {
  const d = new Date(date);
  d.setHours(0, 0, 0, 0);
  return d;
}

function endOfDay(date) {
  const d = new Date(date);
  d.setHours(23, 59, 59, 999);
  return d;
}

console.log(startOfDay(new Date()).toISOString());
// "2024-01-08T00:00:00.000Z"

Anfang/Ende der Woche

function startOfWeek(date) {
  const d = new Date(date);
  const day = d.getDay();
  const diff = d.getDate() - day + (day === 0 ? -6 : 1);
  d.setDate(diff);
  return startOfDay(d);
}

function endOfWeek(date) {
  const d = startOfWeek(new Date(date));
  d.setDate(d.getDate() + 6);
  return endOfDay(d);
}

console.log(startOfWeek(new Date(2024, 0, 8)).toISOString());
// "2024-01-01T00:00:00.000Z" (Monday)

Anfang/Ende des Monats

function startOfMonth(date) {
  return new Date(date.getFullYear(), date.getMonth(), 1);
}

function endOfMonth(date) {
  return new Date(date.getFullYear(), date.getMonth() + 1, 0);
}

console.log(startOfMonth(new Date(2024, 0, 15)).toISOString());
// "2024-01-01T00:00:00.000Z"

console.log(endOfMonth(new Date(2024, 0, 15)).toISOString());
// "2024-01-31T00:00:00.000Z"

Altersberechnung

function calculateAge(birthDate) {
  const today = new Date();
  const birth = new Date(birthDate);

  let years = today.getFullYear() - birth.getFullYear();
  const monthDiff = today.getMonth() - birth.getMonth();

  if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
    years--;
  }

  return years;
}

console.log(calculateAge('1990-06-15'));
// 33 (assuming current date is 2024-01-08)

Berechnung der Werktage

function addBusinessDays(startDate, days) {
  const result = new Date(startDate);
  let addedDays = 0;

  while (addedDays < days) {
    result.setDate(result.getDate() + 1);
    const dayOfWeek = result.getDay();

    if (dayOfWeek !== 0 && dayOfWeek !== 6) {  // Not weekend
      addedDays++;
    }
  }

  return result;
}

console.log(addBusinessDays(new Date(2024, 0, 8), 5).toISOString());
// "2024-01-15T00:00:00.000Z" (skips weekend)

Beispiele und Anwendungsfälle

Countdown-Timer

function countdown(targetDate) {
  const now = Date.now();
  const target = new Date(targetDate).getTime();
  const diff = target - now;

  if (diff <= 0) {
    return { expired: true };
  }

  const days = Math.floor(diff / (1000 * 60 * 60 * 24));
  const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
  const seconds = Math.floor((diff % (1000 * 60)) / 1000);

  return {
    expired: false,
    days,
    hours,
    minutes,
    seconds,
    totalMs: diff
  };
}

console.log(countdown('2024-12-31'));
// { expired: false, days: 357, hours: 11, minutes: 29, seconds: 12, totalMs: ... }

Relative Zeit (z. B. „vor 2 Stunden“)

function timeAgo(timestamp) {
  const now = Date.now();
  const diff = now - timestamp;
  const seconds = Math.floor(diff / 1000);

  if (seconds < 60) return 'just now';
  const minutes = Math.floor(seconds / 60);
  if (minutes < 60) return `${minutes} minute${minutes !== 1 ? 's' : ''} ago`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours} hour${hours !== 1 ? 's' : ''} ago`;
  const days = Math.floor(hours / 24);
  if (days < 30) return `${days} day${days !== 1 ? 's' : ''} ago`;
  const months = Math.floor(days / 30);
  if (months < 12) return `${months} month${months !== 1 ? 's' : ''} ago`;
  const years = Math.floor(days / 365);
  return `${years} year${years !== 1 ? 's' : ''} ago`;
}

const oneHourAgo = Date.now() - (60 * 60 * 1000);
console.log(timeAgo(oneHourAgo));  // "1 hour ago"

Datumsbereichsvalidierung

function isDateInRange(date, startDate, endDate) {
  const timestamp = date.getTime();
  return timestamp >= startDate.getTime() && timestamp <= endDate.getTime();
}

// Example: Check if date is in Q1 2024
const q1Start = new Date(2024, 0, 1);
const q1End = new Date(2024, 2, 31);
const testDate = new Date(2024, 1, 15);

console.log(isDateInRange(testDate, q1Start, q1End));  // true
console.log(isDateInRange(new Date(2024, 3, 1), q1Start, q1End));  // false

Best Practices-Zusammenfassung

JavaScript-Datumscheckliste

✅ Always use ISO 8601 format ('2024-01-08T14:30:00.000Z') for strings
✅ Work with timestamps internally, convert to Date only for display
✅ Use toISOString() for API calls and database storage
✅ Remember months are 0-indexed (0 = January, 11 = December)
✅ Cache timezone offset and Date.now() to avoid repeated calls
✅ Validate dates with isNaN(date.getTime())
✅ Use Intl.DateTimeFormat for i18n-aware formatting
✅ Consider libraries (date-fns, luxon, day.js) for complex operations
✅ Use timestamp arithmetic for precision (add/subtract milliseconds)
✅ Handle date overflow gracefully (JavaScript auto-adjusts)
❌ Don't use locale-specific strings for parsing (inconsistent across browsers)
❌ Don't mix UTC and local methods in same calculation
❌ Don't create Date objects in loops (reuse or use timestamps)
❌ Don't assume browser timezones (always validate with getTimezoneOffset)
❌ Don't rely on automatic string parsing (use ISO 8601)
❌ Don't forget about DST transitions when calculating business days

Leistungstipps

✅ Cache Date.now() instead of calling repeatedly
✅ Use timestamps for comparisons (faster than Date objects)
✅ Minimize Date object creation in loops
✅ Use Math.floor() instead of bitwise operators for readability
✅ Store timezone offset as constant for repeated calculations
❌ Don't use Date.parse() on non-ISO strings (unreliable)
❌ Don't create Date objects in hot code paths
❌ Don't use toLocaleString() in performance-critical sections

Verwandte Tools

Zusätzliche Ressourcen

Für Produktionsanwendungen mit komplexen Datums-/Uhrzeitanforderungen sollten Sie die Verwendung von Bibliotheken wie den folgenden in Betracht ziehen:

  • date-fns: Modulare, unveränderliche Datumsdienstprogramme
  • Luxon: Moderne API mit Zeitzonenunterstützung (von Moment.js-Erstellern)
  • day.js: Leichte Alternative zu Moment.js (2 KB)
  • temporal-polyfill: Zukünftiger TC39-Temporal-API-Vorschlag

Native Date ist für grundlegende Vorgänge ausreichend, aber Bibliotheken bieten eine bessere Ergonomie und Zeitzonenbehandlung für komplexe Anwendungsfälle.