MySQL aktueller Zeitstempel: NOW(), CURRENT_TIMESTAMP, SYSDATE(), UTC und bewährte Verfahren

目次

1. Das kürzeste SQL, um das aktuelle Datum/Uhrzeit in MySQL zu erhalten

Wenn Sie das aktuelle Datum/Uhrzeit in MySQL erhalten möchten, sind die ersten zu merkenden Funktionen NOW() und CURRENT_TIMESTAMP. Nachfolgend finden Sie die kürzesten SQL‑Beispiele nach Anwendungsfall.

1.1 Das aktuelle Datum/Uhrzeit erhalten (einfach)

SELECT NOW();

or

SELECT CURRENT_TIMESTAMP;
  • Beide geben das aktuelle Datum/Uhrzeit (YYYY-MM-DD HH:MM:SS) zurück.
  • Innerhalb derselben Abfrage ist die Zeit zum „Abfrage‑Startzeitpunkt“ festgelegt.

Anwendungsfälle

  • Protokollierung
  • Erstellen eines Zeitstempels für die Datensatzanlage
  • Abrufen einer Referenzzeit

Häufiger Fehler

  • Die Zeitzone der Anwendung und die der Datenbank unterscheiden sich, was zu „Zeitverschiebungen“ führt. → Prüfen Sie mit SELECT @@session.time_zone;

1.2 Nur das heutige Datum erhalten

SELECT CURDATE();
  • Rückgabeformat: YYYY-MM-DD
  • Typ ist DATE (nur Datum, kein Datum‑Uhrzeit)

Anwendungsfälle

  • Suche nach „heutigen Daten“
  • Tägliche Aggregation

Hinweise

  • Im Gegensatz zu NOW() enthält es keine Zeit.
  • Wenn Sie Zeit für Bereichsabfragen benötigen, verwenden Sie NOW().

1.3 Nur die aktuelle Uhrzeit erhalten

SELECT CURTIME();
  • Rückgabeformat: HH:MM:SS
  • Typ ist TIME (nur Uhrzeit)

Anwendungsfälle

  • Anzeige der Ausführungszeit von Stapelprozessen
  • Nur den Zeitanteil in Protokollen ausgeben

Häufiger Stolperstein

  • Da es kein Datum enthält, kann es nicht für Datum‑Uhrzeit‑Vergleiche verwendet werden.

1.4 Die aktuelle Uhrzeit in UTC erhalten (wichtig)

SELECT UTC_TIMESTAMP();
  • Gibt UTC zurück, unabhängig von der Server‑Zeitzone.
  • Empfohlen für globale Dienste.

Grundrichtlinie in realen Projekten

  • In UTC speichern
  • Beim Anzeigen in die lokale Zeit konvertieren

Hinweise

  • Wenn die Anwendung bereits in UTC konvertiert, achten Sie auf eine doppelte Konvertierung.

1.5 Millisekunden / Mikrosekunden erhalten

SELECT NOW(3);  -- milliseconds (3 digits after the decimal point)
SELECT NOW(6);  -- microseconds (6 digits after the decimal point)
  • Verfügbar in MySQL 5.6.4 und später.
  • Wird für hochpräzise Protokolle und Transaktionsprüfungen verwendet.

Häufiges Missverständnis

  • NOW() allein kann keine Bruchteile von Sekunden zurückgeben.
  • Ihre Spalte muss ebenfalls die Präzision angeben, z. B. DATETIME(6).

1.6 Beste Funktion nach Anwendungsfall (bei Unsicherheit hier beginnen)

Use caseRecommended function
General current datetimeNOW()
Table default valueCURRENT_TIMESTAMP
Date onlyCURDATE()
Time onlyCURTIME()
Unified UTC managementUTC_TIMESTAMP()
High-precision logsNOW(6)

Wichtige Punkte, die häufig übersehen werden

  • NOW() und CURRENT_TIMESTAMP sind im Wesentlichen äquivalent (gleicher Wert)
  • Innerhalb derselben Abfrage ist die Zeit festgelegt
  • Der angezeigte Wert ändert sich je nach Zeitzoneneinstellungen
  • Für Mikrosekunden muss Ihre Spaltendefinition die Präzision angeben

2. Unterschiede zwischen NOW() / CURRENT_TIMESTAMP / SYSDATE()

Es gibt mehrere Funktionen, um die aktuelle Zeit zu erhalten, aber der verwirrendste Teil ist der Unterschied zwischen NOW(), CURRENT_TIMESTAMP und SYSDATE().
Wenn Sie das nicht korrekt verstehen, kann es zu unerwartetem Verhalten in Protokollen und bei der Transaktionsverarbeitung kommen.

2.1 NOW() und CURRENT_TIMESTAMP sind im Wesentlichen äquivalent

SELECT NOW(), CURRENT_TIMESTAMP;
  • Beide geben das aktuelle Datum/Uhrzeit (ein DATETIME‑Wert) zurück.
  • Innerhalb derselben Abfrage ist die Zeit zum „Abfrage‑Startzeitpunkt“ festgelegt.
  • CURRENT_TIMESTAMP kann auch mit Funktionsaufruf‑Syntax verwendet werden:
    SELECT CURRENT_TIMESTAMP();
    

Wie man in realen Projekten wählt

Use caseRecommended
Simple retrievalNOW()
Table DEFAULT / ON UPDATECURRENT_TIMESTAMP

Wichtige Punkte

  • Die Bedeutung des abgerufenen Wertes ist identisch.
  • Der Hauptunterschied liegt in Syntax/Verwendung (z. B. in DEFAULT erlaubt).
  • Es handelt sich nicht um einen Typunterschied (leicht misszuverstehen).

2.2 SYSDATE() gibt die Zeit zum „Auswertungszeitpunkt“ zurück

SYSDATE() sieht ähnlich aus wie NOW(), aber der Zeitpunkt, zu dem der Wert festgelegt wird, ist anders.

SELECT NOW(), SLEEP(2), NOW();

Ergebnis (Beispiel):

2025-02-23 14:00:00
2025-02-23 14:00:00
SELECT SYSDATE(), SLEEP(2), SYSDATE();

Ergebnis (Beispiel):

2025-02-23 14:00:00
2025-02-23 14:00:02

Der wesentliche Unterschied

FunctionWhen the time is fixed
NOW()Query start time
SYSDATE()Evaluation time

2.3 Hinweise zu Transaktionen und Replikation

Da NOW() zum Beginn der Abfrage festgelegt ist, ist es
sicherer, wenn Sie innerhalb einer Transaktion eine konsistente Referenzzeit benötigen.

Andererseits kann SYSDATE(), da es vom Ausführungszeitpunkt abhängt, die Reproduzierbarkeit beeinflussen in:

  • Replikation
  • Batch-Jobs
  • Massenprotokollverarbeitung

Daumenregel

  • Möchten Sie eine feste Referenzzeit → NOW()
  • Benötigen Sie jedes Mal den genauen Moment → SYSDATE() (eingeschränkte Verwendung)

2.4 Hinweis: CURRENT_DATE / CURRENT_TIME / LOCALTIME

MySQL unterstützt außerdem:

SELECT CURRENT_DATE;
SELECT CURRENT_TIME;
SELECT LOCALTIME;
  • CURRENT_DATE → gleich wie CURDATE()
  • CURRENT_TIME → gleich wie CURTIME()
  • LOCALTIME → gleich wie NOW()

Allgemeine Verwirrung

  • Dies sind meist „kosmetische Unterschiede“; funktional gibt es kaum Unterschiede.
  • Zur Sicherheit sollten Sie die Lesbarkeit priorisieren und innerhalb des Projekts standardisieren.

Wichtigste Erkenntnisse aus diesem Abschnitt

  • NOW() und CURRENT_TIMESTAMP bedeuten im Wesentlichen dasselbe.
  • SYSDATE() verhält sich anders, weil es auf dem Auswertungszeitpunkt basiert.
  • Für feste Referenzzeiten verwenden Sie standardmäßig NOW().
  • Verwenden Sie CURRENT_TIMESTAMP für DEFAULT und ON UPDATE.

3. Anzeigeformat des aktuellen Datums/Uhrzeit ändern

Die aktuelle Zeit, die Sie mit NOW() erhalten, wird standardmäßig als YYYY-MM-DD HH:MM:SS angezeigt. In der Praxis benötigen Sie häufig Dinge wie:

  • Nur Datum anzeigen
  • YYYY/MM/DD verwenden
  • Ein lokales Format verwenden (z. B. 23. Feb. 2025)
  • Millisekunden anzeigen

Dafür verwenden Sie DATE_FORMAT() (konvertiert ein datetime in ein beliebiges Zeichenkettenformat).

3.1 Grundsyntax von DATE_FORMAT()

DATE_FORMAT(datetime, 'format_string')

Beispiel: Aktuelle Zeit in YYYY/MM/DD HH:MM konvertieren

SELECT DATE_FORMAT(NOW(), '%Y/%m/%d %H:%i');

Beispielausgabe:

2025/02/23 14:35

Häufige Formatbezeichner

SpecifierMeaningExample
%Y4-digit year2025
%m2-digit month02
%d2-digit day23
%HHour (24-hour)14
%iMinutes35
%sSeconds50
%fMicroseconds123456

Hinweise

  • Einige Bezeichner unterscheiden sich zwischen Groß- und Kleinschreibung.
  • %h ist 12‑Stunden‑Zeit, %H ist 24‑Stunden‑Zeit.

3.2 Häufige Formatbeispiele (häufig in der Praxis)

1. Durch Schrägstrich getrennt

SELECT DATE_FORMAT(NOW(), '%Y/%m/%d');

2. Lokalisiert (Englisch)

SELECT DATE_FORMAT(NOW(), '%b %d, %Y');

3. Ohne Sekunden

SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i');

Häufige Falle

  • Da es eine Zeichenkette zurückgibt, können Sie es nicht für numerische Berechnungen verwenden.
  • Für Vergleiche und Suchen sollten Sie den ursprünglichen DATETIME‑Typ verwenden.

3.3 Nur das Datum‑ oder Zeit‑Teil extrahieren

Sie können auch Teile abrufen, während Sie den Typ beibehalten (statt in eine Zeichenkette zu formatieren).

SELECT DATE(NOW());   -- date only (DATE type)
SELECT TIME(NOW());   -- time only (TIME type)
SELECT YEAR(NOW());   -- year only
SELECT MONTH(NOW());  -- month only
SELECT DAY(NOW());    -- day only

Empfohlene Verwendung

GoalRecommended
Formatting for displayDATE_FORMAT
Calculation / comparisonDATE() / TIME()

3.4 Anzeige mit Mikrosekunden

Wenn Sie hochpräzise Protokolle benötigen:

SELECT NOW(6);

Mit Formatierung:

SELECT DATE_FORMAT(NOW(6), '%Y-%m-%d %H:%i:%s.%f');

Wichtige Hinweise

  • Ihre Spalte muss DATETIME(6) oder TIMESTAMP(6) sein, sonst wird die Präzision nicht gespeichert.
  • Nicht verfügbar in MySQL‑Versionen älter als 5.6.4 (umgebungsabhängig).

Häufige Fehler

  • Using DATE_FORMAT() in a WHERE clause prevents indexes from being used. wp:list /wp:list

    • Schlechtes Beispiel: WHERE DATE_FORMAT(created_at, '%Y-%m-%d') = '2025-02-23'
    • Empfohlen: WHERE created_at >= '2025-02-23 00:00:00' AND created_at < '2025-02-24 00:00:00'
    • Das direkte Speichern der formatieren Anzeigezeichenkette (verschlechtert die Suchleistung)

Wichtigste Erkenntnisse aus diesem Abschnitt

  • DATE_FORMAT() verwenden, um Anzeigeformate zu ändern.
  • Für Berechnungen/Vergleiche den ursprünglichen Typ beibehalten.
  • Wenn Sie Mikrosekunden benötigen, die Präzision in der Spaltendefinition angeben.
  • Die Verwendung von Funktionen in WHERE‑Klauseln kann Leistungsprobleme verursachen.

4. Datums‑Zeit‑Berechnungen mit der aktuellen Zeit

In MySQL ist es üblich, Dinge wie „N Stunden später“, „N Tage zuvor“ oder „die letzten N Tage“ basierend auf der aktuellen Zeit zu berechnen.
Der häufigste Anwendungsfall in der Praxis ist „Daten der letzten 24 Stunden abrufen.“

Die Grundlage der Datums‑ und Zeitarithmetik ist INTERVAL (Syntax zum Hinzufügen/Entfernen von Zeiteinheiten).

4.1 Hinzufügen/Entfernen mit INTERVAL

1 Stunde später

SELECT NOW() + INTERVAL 1 HOUR;

Vor 3 Tagen

SELECT NOW() - INTERVAL 3 DAY;

1 Monat später

SELECT NOW() + INTERVAL 1 MONTH;

Gemeinsame Einheiten

UnitMeaning
SECONDSeconds
MINUTEMinutes
HOURHours
DAYDays
WEEKWeeks
MONTHMonths
YEARYears

Häufige Fehler

  • DAY in INTERVAL 1 DAY funktioniert auch in Kleinbuchstaben, aber Sie sollten im Team eine einheitliche Schreibweise verwenden.
  • Berechnungen am Monatsende können von den Erwartungen abweichen, weil die Anzahl der Tage variiert (z. B. 31. Jan + 1 Monat).

4.2 Daten der letzten 24 Stunden abrufen (häufigstes Muster)

SELECT *
FROM users
WHERE created_at >= NOW() - INTERVAL 1 DAY;

Bedeutung

  • Ziel: „von jetzt an zurück bis vor 24 Stunden.“

Hinweise

  • Wenn Sie CURDATE() verwenden, wird die Basis zu „heute um 00:00“, was die Bedeutung ändert.

Beispiel (Daten von heute):

SELECT *
FROM users
WHERE created_at >= CURDATE();

Das Verständnis des Unterschieds ist entscheidend

ExpressionMeaning
NOW() - INTERVAL 1 DAYPast 24 hours
CURDATE()Since today 00:00

4.3 Tagesdifferenzen mit DATEDIFF() ermitteln

SELECT DATEDIFF('2025-03-01', '2025-02-23');

Ergebnis:

6
  • Einheit ist „Tage“
  • Der Zeitanteil wird ignoriert

Hinweise

  • Das Vorzeichen ändert sich je nach Reihenfolge der Argumente.
  • Sie können keine Differenzen in Stunden/Minuten/Sekunden berechnen.

4.4 TIMESTAMPDIFF() für Stunden/Minuten/Sekunden verwenden

SELECT TIMESTAMPDIFF(HOUR,
                     '2025-02-23 12:00:00',
                     '2025-02-23 18:30:00');

Ergebnis:

6

Minuten

SELECT TIMESTAMPDIFF(MINUTE,
                     '2025-02-23 12:00:00',
                     '2025-02-23 12:30:00');

Sekunden

SELECT TIMESTAMPDIFF(SECOND,
                     '2025-02-23 12:00:00',
                     '2025-02-23 12:00:45');

Anwendungsfälle

  • Berechnung der Sitzungsdauer
  • Ablaufprüfungen
  • Timeout-Entscheidungen

4.5 Monatsanfang / Monatsende ermitteln (häufige Falle in der Praxis)

Ersten Tag dieses Monats erhalten:

SELECT DATE_FORMAT(NOW(), '%Y-%m-01');

Erster Tag des nächsten Monats:

SELECT DATE_FORMAT(NOW() + INTERVAL 1 MONTH, '%Y-%m-01');

Hinweise

  • Das Monatsende ist kein festes Datum.
  • Für Bereichsabfragen ist “>= start AND < erster Tag des nächsten Monats” sicher.

Zusammenfassung häufiger Fehler

  • Verwendung von BETWEEN mit nur Datumswerten und Vergessen der Zeit
  • Deaktivierung von Indizes durch Nutzung von DATE(created_at) in WHERE‑Klauseln
  • In die „31‑Tage‑Problematik“ bei Monatsberechnungen geraten
  • Missverständnis des Unterschieds zwischen NOW() und CURDATE()

Wichtige Erkenntnisse aus diesem Abschnitt

  • INTERVAL ist die Grundlage der Datums‑ und Zeitarithmetik.
  • Letzte 24 Stunden = NOW() - INTERVAL 1 DAY.
  • Tage = DATEDIFF(); kleinere Einheiten = TIMESTAMPDIFF().
  • Seien Sie vorsichtig bei Endbedingungen für monatsbasierte Berechnungen.

5. Für Bereichsabfragen ist dies sicherer als BETWEEN

Bei Datum‑Bereichssuchen in MySQL verwenden viele Anfänger BETWEEN. Allerdings führt dies häufig zu unerwarteten Ergebnissen, wenn Zeitgrenzen nicht korrekt behandelt werden, daher wird in der Praxis ein sichereres Muster empfohlen.

5.1 Grundlagen von BETWEEN und die Fallstricke

Eine häufige Abfrage

SELECT *
FROM orders
WHERE order_date BETWEEN '2025-02-01' AND '2025-02-10';

Sie sieht korrekt aus, ist intern aber äquivalent zu:

WHERE order_date &gt;= '2025-02-01 00:00:00'
  AND order_date &lt;= '2025-02-10 00:00:00'

Also schließt sie keine Daten nach 00:00 am 10. Februar ein.


5.2 Sichereres Muster (empfohlen)

Empfohlenes Muster

SELECT *
FROM orders
WHERE order_date &gt;= '2025-02-01 00:00:00'
  AND order_date &lt;  '2025-02-11 00:00:00';

Wichtige Punkte

  • Geben Sie die Endgrenze als „weniger als der nächste Tag um 00:00“ an
  • Sicherer als <= 23:59:59 (unterstützt Mikrosekunden)

5.3 Der korrekte Weg, die heutigen Daten zu erhalten

Schlechtes Beispiel:

WHERE DATE(created_at) = CURDATE();

Probleme:

  • Das Anwenden einer Funktion auf die Spalte deaktiviert Indizes
  • Kann bei großen Tabellen zu erheblichen Verlangsamungen führen

Empfohlen:

WHERE created_at &gt;= CURDATE()
  AND created_at &lt;  CURDATE() + INTERVAL 1 DAY;

Dies stellt sicher:

  • Indizes können verwendet werden
  • Schnelle Suchen
  • Keine Grenzprobleme

5.4 Sichere Muster für die letzten 7 / letzten 30 Tage

Letzte 7 Tage

WHERE created_at &gt;= NOW() - INTERVAL 7 DAY;

Letzte 30 Tage

WHERE created_at &gt;= NOW() - INTERVAL 30 DAY;

Hinweise

  • CURDATE() - INTERVAL 7 DAY basiert auf „heute 00:00“
  • NOW() - INTERVAL 7 DAY basiert auf „aktueller Zeit“
  • Wählen Sie je nach Anforderung

5.5 Wichtige Regel, um Indizes wirksam zu halten

Schlecht:

WHERE DATE(created_at) = '2025-02-23';

Gut:

WHERE created_at &gt;= '2025-02-23 00:00:00'
  AND created_at &lt;  '2025-02-24 00:00:00';

Warum:

  • Indizes funktionieren auf „der Spalte selbst“
  • Das Anwenden einer Funktion verhindert die Indexnutzung (Vollscan)

Zusammenfassung häufiger Fehler

  • Vergessen, die Zeit an der Endgrenze in BETWEEN einzuschließen
  • Fehlende Mikrosekunden bei Verwendung von 23:59:59
  • DATE() in WHERE‑Klauseln verwenden und Abfragen verlangsamen
  • „now“ vs. „today 00:00“ unklar lassen

Wichtige Erkenntnisse aus diesem Abschnitt

  • Bereichsabfragen sind am sichersten mit >= start AND < end .
  • BETWEEN erfordert sorgfältige Grenzbehandlung.
  • Um Indizes wirksam zu halten, sollten Spalten nicht in Funktionen eingeschlossen werden.
  • Wählen Sie eindeutig zwischen NOW()‑basierter und CURDATE()‑basierter Logik.

6. DEFAULT CURRENT_TIMESTAMP und ON UPDATE (Grundlagen des Tabellendesigns)

Im Datenbankdesign ist es üblich, created_at und updated_at automatisch zu verwalten.
In MySQL ermöglicht CURRENT_TIMESTAMP, die aktuelle Zeit bei INSERT und UPDATE automatisch zu setzen.

6.1 Automatisches Setzen von created_at (DEFAULT CURRENT_TIMESTAMP)

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Verhalten:

INSERT INTO users (name) VALUES ('Alice');

→ Die aktuelle Zeit wird automatisch in created_at eingefügt.

Wichtige Punkte

  • CURRENT_TIMESTAMP kann in DEFAULT verwendet werden.
  • NOW() kann nicht direkt in DEFAULT verwendet werden.

Häufiger Fehler

created_at DATETIME DEFAULT NOW();  -- error

Grund:

  • In MySQL kann man im Allgemeinen keine Funktion als DEFAULT setzen (Ausnahme ist CURRENT_TIMESTAMP).

6.2 Automatisches Aktualisieren von updated_at (ON UPDATE)

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
               ON UPDATE CURRENT_TIMESTAMP
);

Verhalten:

UPDATE users SET name = 'Bob' WHERE id = 1;

updated_at wird automatisch auf die aktuelle Zeit aktualisiert.

Anwendungsfälle

  • Verfolgung des letzten Logins
  • Aktualisierungshistorie
  • Audit‑Logs

6.3 DATETIME vs TIMESTAMP (wichtig)

TypeRangeTime zone impact
DATETIMEYear 1000 to 9999No
TIMESTAMP1970 to 2038Yes

Der wesentliche Unterschied

  • TIMESTAMP wird intern in UTC gespeichert und bei der Anzeige in die Zeitzone der Session konvertiert.
  • DATETIME speichert den wörtlichen Wert (keine Konvertierung).

Richtlinien

CaseRecommended type
Log managementTIMESTAMP
Future dates (after 2038)DATETIME
Fixed values not requiring TZ conversionDATETIME

6.4 CURRENT_TIMESTAMP kann auch mit DATETIME verwendet werden

In MySQL 5.6 und später kann man CURRENT_TIMESTAMP ebenfalls als DEFAULT und ON UPDATE für DATETIME‑Spalten angeben.

created_at DATETIME DEFAULT CURRENT_TIMESTAMP

Hinweise

  • Ältere MySQL‑Versionen haben Einschränkungen (umgebungsabhängig).
  • Falls Sie Präzision benötigen:
    DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6)
    

6.5 Wenn Sie NOW() verwenden möchten: eine Alternative (Trigger)

CREATE TRIGGER set_created_at
BEFORE INSERT ON logs
FOR EACH ROW
SET NEW.created_at = NOW();

Anwendungsfälle

  • Komplexe Logik für Anfangswerte
  • Bedingte Zuweisung von Zeitstempeln

Notizen

  • Triggers sind schwer zu debuggen.
  • Vermeiden Sie sie, es sei denn, notwendig.

Häufige Designfehler

  • Hinzufügen von ON UPDATE zu beiden created_at und updated_at
  • Verwechslung des Verhaltens von DATETIME und TIMESTAMP
  • Verschiebung von Entscheidungen zu Zeitzonen

Wichtige Erkenntnisse aus diesem Abschnitt

  • Verwenden Sie CURRENT_TIMESTAMP für DEFAULT.
  • Verwenden Sie ON UPDATE CURRENT_TIMESTAMP für die Aktualisierungstracking.
  • Wählen Sie Typen basierend auf Zeitzonenverhalten und dem 2038-Problem.
  • Wenn Sie Präzision benötigen, vergessen Sie nicht (6) .

7. Zeitzonendesign (in UTC speichern, in lokaler Zeit anzeigen)

Beim Umgang mit der aktuellen Zeit verursacht schlechtes Zeitzonendesign Zeitdrift und doppelte Konvertierung.
In der Praxis ist der sicherste Standard „in UTC speichern, für die Anzeige in lokale Zeit konvertieren.“

MySQL timezone architecture storing timestamps in UTC and converting to local time (JST)

Abbildung: Grundlegende Architektur für die Speicherung von UTC in MySQL und die Anzeige lokaler Zeit

7.1 Überprüfen der aktuellen Zeitzone

Zuerst überprüfen, in welcher Zeitzone MySQL läuft.

SELECT @@global.time_zone, @@session.time_zone;
  • @@global.time_zone → serverweite Einstellung
  • @@session.time_zone → Einstellung für die aktuelle Verbindung/Sitzung
  • Wenn es SYSTEM anzeigt, hängt es von der OS-Einstellung ab

Häufige Probleme

  • Produktions- und Entwicklungsserver haben unterschiedliche OS-Zeitzonen
  • Die App konvertiert zu UTC, und die DB konvertiert erneut (doppelte Konvertierung)

7.2 Ändern der Zeitzone pro Sitzung

SET time_zone = 'Asia/Tokyo';

oder einheitlich auf UTC umstellen:

SET time_zone = '+00:00';

Wichtige Punkte

  • Es kehrt zurück, wenn die Verbindung geschlossen wird
  • Wenn Sie Connection Pooling verwenden, überprüfen Sie die Anwendungseinstellungen

7.3 Warum in UTC speichern (Realwelt-Prinzip)

Empfohlene Richtlinie

  1. Daten in UTC speichern
  2. Bei der Anzeige in die Zeitzone des Benutzers konvertieren

Gründe:

  • Einfachere internationale Unterstützung
  • Vermeidung von Problemen mit Sommerzeit (DST)
  • Minimierung des Einflusses beim Verschieben von Servern

UTC abrufen:

SELECT UTC_TIMESTAMP();

7.4 Zeitzonen mit CONVERT_TZ() konvertieren

Beispiel: UTC → JST

SELECT CONVERT_TZ('2025-02-23 05:35:00', '+00:00', '+09:00');

Verwendung von Zeitzonennamen:

SELECT CONVERT_TZ('2025-02-23 05:35:00', 'UTC', 'Asia/Tokyo');

Realwelt-Beispiel

SELECT CONVERT_TZ(created_at, 'UTC', 'Asia/Tokyo')
FROM users;

7.5 Warum CONVERT_TZ() NULL zurückgibt

Wenn es NULL zurückgibt, sind häufige Ursachen:

  • MySQL-Zeitzonentabellen sind nicht geladen
  • Der angegebene Zeitzonenname existiert nicht

Beispiel-Laden unter Linux:

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql

Notizen

  • In der Produktion Berechtigungen bestätigen und ob ein Neustart erforderlich ist
  • In Docker kann zoneinfo je nach Image nicht enthalten sein

7.6 Serverweite Zeitzone ändern

Konfigurationsdatei (my.cnf / my.ini):

[mysqld]
default_time_zone = '+00:00'

Nach dem Neustart überprüfen:

SELECT @@global.time_zone;

Wichtig

  • Bei Produktionsänderungen den Umfang der Auswirkungen bestätigen
  • Vorsicht mit bestehenden Daten (manchmal ändert sich nur die Anzeige)

Häufige Fehler

  • Lokale Zeit statt UTC speichern und später internationale Unterstützung hinzufügen
  • Doppelte Konvertierung zwischen App und DB
  • Design mit DATETIME ohne Berücksichtigung von Zeitzonen
  • Unterschiedliche TZ-Einstellungen zwischen Test und Produktion

Wichtige Erkenntnisse aus diesem Abschnitt

  • In UTC speichern und bei der Anzeige konvertieren.
  • Verwenden Sie UTC_TIMESTAMP() .
  • Bei der Verwendung von CONVERT_TZ() die TZ-Tabellen überprüfen.
  • Immer Umgebungsunterschiede in Zeitzonen berücksichtigen.

8. Praktische Beispiele, die Sie direkt verwenden können

Hier sind konkrete SQL-Beispiele, die zeigen, wie Sie die aktuelle MySQL-Zeit in der realen Entwicklung/Betrieb verwenden.
Sie sind so geschrieben, dass Sie sie direkt kopieren und einfügen können.

8.1 Automatisches Einfügen der aktuellen Zeit in Logs

Tabelle erstellen

CREATE TABLE system_logs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    level VARCHAR(50),
    message TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Log einfügen

INSERT INTO system_logs (level, message)
VALUES ('ERROR', 'Failed to connect to the DB');

Wichtige Punkte

  • created_at wird automatisch eingefügt
  • Es ist nicht nötig, einen Zeitstempel aus der Anwendung zu übergeben
  • Wesentliches Design für Audits und Vorfalluntersuchungen

Häufige Fehler

  • Zeit sowohl in der Anwendung als auch in der Datenbank verwalten
  • Zeitinkonsistenzen aufgrund nicht einheitlicher Zeitzonen

8.2 Letzte Anmeldezeit aktualisieren

Tabellendesign

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(255),
    last_login TIMESTAMP DEFAULT CURRENT_TIMESTAMP
               ON UPDATE CURRENT_TIMESTAMP
);

Aktualisierung bei Anmeldung

UPDATE users
SET last_login = NOW()
WHERE id = 1;

Hinweise

  • ON UPDATE wird nur ausgelöst, wenn sich die Spalte ändert
  • Einige UPDATE-Anweisungen ändern den Wert möglicherweise nicht und führen daher kein Update aus

8.3 Referenzzeit in Batch-Jobs fixieren

Für langlaufende Prozesse ist es sicherer, eine Referenzzeit festzulegen.

SET @base_time = NOW();

SELECT *
FROM orders
WHERE created_at &gt;= @base_time - INTERVAL 1 DAY;

Warum

  • Die Zeit verschiebt sich nicht während des Prozesses
  • Konsistenz wird aufrechterhalten

8.4 Aggregation für heute / gestern / letzte 7 Tage

Verkäufe von heute

SELECT SUM(amount)
FROM orders
WHERE created_at &gt;= CURDATE()
  AND created_at &lt;  CURDATE() + INTERVAL 1 DAY;

Verkäufe von gestern

SELECT SUM(amount)
FROM orders
WHERE created_at &gt;= CURDATE() - INTERVAL 1 DAY
  AND created_at &lt;  CURDATE();

Letzte 7 Tage

SELECT COUNT(*)
FROM users
WHERE created_at &gt;= NOW() - INTERVAL 7 DAY;

Wichtig

  • Wenden Sie keine Funktionen auf Spalten in WHERE‑Klauseln an
  • Schreiben Sie Bedingungen, die Indexe nutzbar halten

8.5 Ablaufprüfungen (Sitzungen/Token)

SELECT *
FROM sessions
WHERE expires_at &gt; NOW();

Abgelaufene Zeilen löschen

DELETE FROM sessions
WHERE expires_at &lt;= NOW();

Häufige Fehler

  • Verwendung von CURDATE() und Ignorieren der Zeit
  • Speicherung in UTC, aber Vergleich mit lokalem NOW()

8.6 Zeilen erhalten, die innerhalb von N Stunden ablaufen

SELECT *
FROM coupons
WHERE expires_at &lt;= NOW() + INTERVAL 1 HOUR;

Anwendungsfälle:

  • Ablaufwarnungen
  • Ablaufbenachrichtigungen

Was Sie immer im Hinterkopf behalten sollten

  • Seien Sie eindeutig, ob Ihre Basiszeit „jetzt“ oder „heute 00:00“ ist
  • Schreiben Sie Prädikate, die Indexe effektiv halten
  • Entscheiden Sie das Zeitzonendesign im Voraus
  • Mischen Sie NOW() und UTC_TIMESTAMP() nicht ohne klare Richtlinie

Wichtige Erkenntnisse aus diesem Abschnitt

  • Für Logs/Audits/Update‑Verfolgung verwenden Sie CURRENT_TIMESTAMP
  • Für Aggregationen verwenden Sie das sichere Muster >= AND <
  • Für Sitzungsmanagement vergleichen Sie mit NOW()
  • Legen Sie eine Basiszeit fest, um die Verarbeitung konsistent zu halten

9. Häufig gestellte Fragen (FAQ)

Hier sind häufige Fragen zur MySQL‑Aktuellen‑Zeit, insbesondere zu Fallstricken, die in der Praxis auftreten.

9.1 Was ist der Unterschied zwischen NOW() und CURRENT_TIMESTAMP?

Fazit: Die Bedeutung des zurückgegebenen Wertes ist identisch.

SELECT NOW(), CURRENT_TIMESTAMP;

Beide geben das aktuelle Datum und die aktuelle Uhrzeit zurück.

Der Hauptunterschied liegt in der syntaktischen Verwendung

  • CURRENT_TIMESTAMP kann in DEFAULT und ON UPDATE verwendet werden
  • NOW() kann nicht direkt in DEFAULT verwendet werden

Hinweise

  • Es ist kein Typunterschied
  • Sie können die Präzision mit Argumenten wie (6) angeben

9.2 Sollten Sie SYSDATE() verwenden?

SYSDATE() gibt die Zeit zum „Auswertungszeitpunkt“ zurück.

SELECT SYSDATE(), SLEEP(2), SYSDATE();

Der Wert kann sich sogar innerhalb derselben Abfrage ändern.

Wann man es verwendet

  • Wenn Sie den genauen realen Zeitmoment festhalten müssen

Wann man es vermeidet

  • Replikation
  • Transaktionsverarbeitung, bei der Konsistenz wichtig ist

In den meisten Fällen ist die Verwendung von NOW() ausreichend.

9.3 Warum wird die Zeit verschoben?

Main causes:

  1. Server‑Zeitzoneneinstellungen
  2. Sitzungs‑Zeitzoneneinstellungen
  3. Doppelte Konvertierung mit der Anwendung
  4. Automatisches Konvertierungsverhalten des TIMESTAMP‑Typs

Check with:

SELECT @@global.time_zone, @@session.time_zone;

Minderung

  • Standardmäßig in UTC speichern
  • Nur bei Anzeige konvertieren
  • Richtlinie zwischen Anwendung und DB vereinheitlichen

9.4 CONVERT_TZ() returns NULL

Ursachen:

  • Zeitzonentabellen sind nicht geladen
  • Falscher Zeitzonenname

Lösung:

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql

Seien Sie besonders vorsichtig in Docker‑Umgebungen.

9.5 Range shifts with BETWEEN

Schlecht:

WHERE created_at BETWEEN '2025-02-01' AND '2025-02-10';

Sicher:

WHERE created_at &gt;= '2025-02-01 00:00:00'
  AND created_at &lt;  '2025-02-11 00:00:00';

Gründe:

  • Problem mit dem Endgrenzzeitpunkt
  • Mikrosekunden‑Leckage
  • Indexeffizienz

9.6 How do you choose between DATETIME and TIMESTAMP?

  • Internationale Unterstützung / UTC‑Verwaltung → TIMESTAMP
  • Nach 2038 oder feste Datumszeiten → DATETIME

Entscheiden Sie dies bereits im Design.

9.7 Microseconds aren’t being stored

Ursache:

  • Keine Präzision in der Spaltendefinition angegeben

Lösung:

created_at DATETIME(6)

Key takeaways from this section

  • Beginnen Sie mit NOW() und CURRENT_TIMESTAMP
  • Für Bereichsabfragen verwenden Sie >= AND <
  • UTC‑Speicherung ist die sicherste Standardeinstellung
  • Vergessen Sie nicht die Typauswahl und Präzision

10. Summary

Dieser Artikel fasst praktische Methoden zum Abrufen, Formatieren, Berechnen und Verwalten der aktuellen Zeit in MySQL zusammen.
Abschließend finden Sie die minimalen Grundlagen, die Sie kennen sollten, um sicher zu bleiben.

10.1 Getting the current time (basics)

  • Allgemeine Abfrage → NOW()
  • Tabellen‑DEFAULT / Aktualisierungsverfolgung → CURRENT_TIMESTAMP
  • Nur Datum → CURDATE()
  • Nur Zeit → CURTIME()
  • UTC → UTC_TIMESTAMP()
  • Hohe Präzision → NOW(6)

Faustregeln

  • Wenn Sie unsicher sind, ist die Verwendung von NOW() in den meisten Fällen in Ordnung.
  • Für das Schema‑Design verwenden Sie CURRENT_TIMESTAMP .

10.2 Range queries: “>= AND <” is the golden rule

Sicheres Muster:

WHERE created_at &gt;= 'START'
  AND created_at &lt;  'END'

Warum:

  • Verhindert fehlende Zeilen am Endgrenzwert
  • Funktioniert mit Mikrosekunden
  • Hält Indizes nutzbar

Schlechtes Beispiel

WHERE DATE(created_at) = CURDATE();

Wickeln Sie die Spalte nicht in eine Funktion ein.

10.3 Datetime arithmetic basics

  • Addieren/ Subtrahieren → INTERVAL
  • Tagesdifferenzen → DATEDIFF()
  • Zeitdifferenzen → TIMESTAMPDIFF()

Behalten Sie stets im Hinterkopf, ob Ihre Basis „now“ oder „today 00:00“ ist.

10.4 Time zone design principles

  • In UTC speichern
  • Bei Anzeige konvertieren
  • Richtlinie zwischen Anwendung und DB vereinheitlichen

Überprüfen mit:

SELECT @@global.time_zone, @@session.time_zone;

10.5 Table design best practices

created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
           ON UPDATE CURRENT_TIMESTAMP
  • Standardausstattung für Auditing/Logging/Aktualisierungsverfolgung
  • Falls Sie Präzision benötigen, geben Sie (6) an

The 4 most important real‑world points

  1. Verwechseln Sie nicht die Unterschiede zwischen NOW() und CURRENT_TIMESTAMP
  2. Für Bereichsabfragen verwenden Sie >= AND <
  3. Standardmäßig in UTC speichern
  4. Entscheiden Sie sich im Design für die Typen (DATETIME vs TIMESTAMP)

Die Handhabung der aktuellen Zeit in MySQL ist grundlegend für Logging, Verkaufsaggregation, Auth‑/Sitzungsverwaltung, Batch‑Jobs und mehr.
Wenn Sie die Prinzipien in diesem Artikel befolgen, können Sie viele gängige Probleme wie Zeitdrift, Grenzfehler und Leistungsverschlechterungen vermeiden.