Zum Inhalt springen

Timestamp-Typen

Timestamps stehen für Zeitpunkte. Sie kombinieren daher Informationen zu DATE und TIME. Sie können mit dem Typnamen gefolgt von einer Zeichenkette im ISO-8601-Format YYYY-MM-DD hh:mm:ss[.zzzzzzzzz][+-TT[:tt]] erzeugt werden, das wir auch in dieser Dokumentation verwenden. Dezimalstellen jenseits der unterstützten Genauigkeit werden ignoriert.

Timestamp-Typen

Name Aliases Beschreibung
TIMESTAMP_NS Naiver Timestamp mit Nanosekundengenauigkeit
TIMESTAMP DATETIME, TIMESTAMP WITHOUT TIME ZONE Naiver Timestamp mit Mikrosekundengenauigkeit
TIMESTAMP_MS Naiver Timestamp mit Millisekundengenauigkeit
TIMESTAMP_S Naiver Timestamp mit Sekundengenauigkeit
TIMESTAMPTZ TIMESTAMP WITH TIME ZONE Zeitzonenbewusster Timestamp mit Mikrosekundengenauigkeit

Warnung Da es derzeit keinen Datentyp TIMESTAMP_NS WITH TIME ZONE gibt, werden externe Spalten mit Nanosekundengenauigkeit und Semantik WITH TIME ZONE, z. B. Parquet-Timestamp-Spalten mit isAdjustedToUTC=true, in TIMESTAMP WITH TIME ZONE umgewandelt und verlieren beim Lesen mit DuckDB daher an Genauigkeit.

SELECT TIMESTAMP_NS '1992-09-20 11:30:00.123456789';
1992-09-20 11:30:00.123456789
SELECT TIMESTAMP '1992-09-20 11:30:00.123456789';
1992-09-20 11:30:00.123456
SELECT TIMESTAMP_MS '1992-09-20 11:30:00.123456789';
1992-09-20 11:30:00.123
SELECT TIMESTAMP_S '1992-09-20 11:30:00.123456789';
1992-09-20 11:30:00
SELECT TIMESTAMPTZ '1992-09-20 11:30:00.123456789';
1992-09-20 11:30:00.123456+00
SELECT TIMESTAMPTZ '1992-09-20 12:30:00.123456789+01:00';
1992-09-20 11:30:00.123456+00

DuckDB unterscheidet Timestamps WITHOUT TIME ZONE und WITH TIME ZONE (deren einziger aktueller Vertreter TIMESTAMP WITH TIME ZONE ist).

Trotz des Namens speichert ein TIMESTAMP WITH TIME ZONE keine Zeitzoneninformation. Stattdessen speichert er nur die INT64-Anzahl der nicht-Schalt-Mikrosekunden seit der Unix-Epoche 1970-01-01 00:00:00+00 und identifiziert damit eindeutig einen Punkt in der absoluten Zeit, oder Instant. Der Grund für die Bezeichnungen zeitzonenbewusst und WITH TIME ZONE ist, dass Timestamp-Arithmetik, Binning und String-Formatierung für diesen Typ in einer konfigurierten Zeitzone erfolgen, die standardmäßig die Systemzeitzone ist und in den Beispielen oben einfach UTC+00:00 ist.

Der entsprechende TIMESTAMP WITHOUT TIME ZONE speichert dasselbe INT64, aber Arithmetik, Binning und String-Formatierung folgen den einfachen Regeln der koordinierten Weltzeit (UTC) ohne Offsets oder Zeitzonen. Entsprechend könnten TIMESTAMPs als UTC-Timestamps interpretiert werden, häufiger werden sie jedoch verwendet, um lokale Zeitbeobachtungen darzustellen, die in einer unspezifizierten Zeitzone aufgezeichnet wurden; Operationen auf diesen Typen können als einfaches Manipulieren von Tupelfeldern nach nominaler zeitlicher Logik interpretiert werden. Ein häufiges Datenbereinigungsproblem besteht darin, solche Beobachtungen, die auch in Roh-Zeichenketten ohne Zeitzonenangabe oder UTC-Offset gespeichert sein können, in eindeutige Instants TIMESTAMP WITH TIME ZONE zu überführen. Eine mögliche Lösung ist, UTC-Offsets an Zeichenketten anzuhängen und anschließend explizit nach TIMESTAMP WITH TIME ZONE zu casten. Alternativ kann zuerst ein TIMESTAMP WITHOUT TIME ZONE erzeugt und dann mit einer Zeitzonenangabe kombiniert werden, um einen zeitzonenbewussten TIMESTAMP WITH TIME ZONE zu erhalten.

Umwandlung zwischen Zeichenketten und naiven / zeitzonenbewussten Timestamps

Die Umwandlung zwischen Zeichenketten ohne UTC-Offsets oder IANA-Zeitzonennamen und Typen WITHOUT TIME ZONE ist eindeutig und geradlinig. Die Umwandlung zwischen Zeichenketten mit UTC-Offsets oder Zeitzonennamen und Typen WITH TIME ZONE ist ebenfalls eindeutig, erfordert aber die Erweiterung ICU zur Behandlung von Zeitzonennamen.

Wenn Zeichenketten ohne UTC-Offsets oder Zeitzonennamen in einen Typ WITH TIME ZONE umgewandelt werden, wird die Zeichenkette in der konfigurierten Zeitzone interpretiert. Wenn Zeichenketten mit UTC-Offsets an einen Typ WITHOUT TIME ZONE übergeben werden, werden die Offsets oder Zeitzonenangaben ignoriert. Wenn Zeichenketten mit anderen Zeitzonennamen als UTC an einen Typ WITHOUT TIME ZONE übergeben werden, wird ein Fehler geworfen.

Schließlich verwendet die Umwandlung zwischen Typen WITH TIME ZONE und WITHOUT TIME ZONE über explizite oder implizite Casts die konfigurierte Zeitzone. Um eine alternative Zeitzone zu verwenden, kann die von der Erweiterung ICU bereitgestellte Funktion timezone verwendet werden:

SELECT
timezone('America/Denver', TIMESTAMP '2001-02-16 20:38:40') AS aware1,
timezone('America/Denver', TIMESTAMPTZ '2001-02-16 04:38:40') AS naive1,
timezone('UTC', TIMESTAMP '2001-02-16 20:38:40+00:00') AS aware2,
timezone('UTC', TIMESTAMPTZ '2001-02-16 04:38:40 Europe/Berlin') AS naive2;
aware1 naive1 aware2 naive2
2001-02-17 04:38:40+01 2001-02-15 20:38:40 2001-02-16 21:38:40+01 2001-02-16 03:38:40

Beachten Sie, dass TIMESTAMPs in den Ergebnissen ohne Zeitzonenangabe angezeigt werden, gemäß den ISO-8601-Regeln für lokale Zeiten, während zeitzonenbewusste TIMESTAMPTZs mit dem UTC-Offset der konfigurierten Zeitzone angezeigt werden, die im Beispiel 'Europe/Berlin' ist. Die UTC-Offsets von 'America/Denver' und 'Europe/Berlin' zu allen beteiligten Instants sind -07:00 bzw. +01:00.

Sonderwerte

Drei besondere Zeichenketten können verwendet werden, um Timestamps zu erzeugen:

Eingabezeichenkette Beschreibung
epoch 1970-01-01 00:00:00[+00] (Unix-Systemzeit null)
infinity Später als alle anderen Timestamps
-infinity Früher als alle anderen Timestamps

Die Werte infinity und -infinity werden besonders behandelt und unverändert angezeigt, während der Wert epoch lediglich eine Schreibabkürzung ist, die beim Einlesen in den entsprechenden Timestamp-Wert umgewandelt wird.

SELECT '-infinity'::TIMESTAMP, 'epoch'::TIMESTAMP, 'infinity'::TIMESTAMP;
Negative Epoch Positive
-infinity 1970-01-01 00:00:00 infinity

Funktionen

Siehe Timestamp-Funktionen.

Zeitzonen

Um Zeitzonen und die Typen WITH TIME ZONE zu verstehen, hilft es, mit zwei Konzepten zu beginnen: Instants und temporales Binning.

Instants

Ein Instant ist ein Punkt in der absoluten Zeit, üblicherweise angegeben als Anzahl eines Zeitinkrements von einem festen Zeitpunkt (der Epoche). Das ähnelt der Angabe von Positionen auf der Erdoberfläche mit Breite und Länge relativ zum Äquator und zum Greenwich-Meridian. In DuckDB ist der feste Punkt die Unix-Epoche 1970-01-01 00:00:00+00:00, und das Inkrement ist in Sekunden, Millisekunden, Mikrosekunden oder Nanosekunden, je nach konkretem Datentyp.

Temporales Binning

Binning ist eine gängige Praxis bei kontinuierlichen Daten: Ein Bereich möglicher Werte wird in zusammenhängende Teilmengen zerlegt, und die Binning-Operation bildet tatsächliche Werte auf den Bin ab, in den sie fallen. Temporales Binning ist einfach die Anwendung dieser Praxis auf Instants; beispielsweise durch Einteilen von Instants in Jahre, Monate und Tage.

Zeitzonen-Instants an der Epoche Zeitzonen-Instants an der Epoche

Die Regeln für temporales Binning sind komplex und kommen im Allgemeinen in zwei Sätzen: Zeitzonen und Kalender. Für die meisten Aufgaben ist der Kalender einfach der weit verbreitete gregorianische Kalender, aber Zeitzonen wenden lokale Regeln an und können stark variieren. So sieht beispielsweise das Binning für die Zeitzone 'America/Los_Angeles' in der Nähe der Epoche aus:

Zwei Zeitzonen an der Epoche Zwei Zeitzonen an der Epoche

Das häufigste Problem beim temporalen Binning tritt bei Änderungen der Sommerzeit auf. Das folgende Beispiel enthält eine Sommerzeitumstellung, bei der der „Stunden“-Bin zwei Stunden lang ist. Um die zwei Stunden zu unterscheiden, wird ein weiterer Bereich von Bins mit dem Offset zu UTC benötigt:

Zwei Zeitzonen bei einer Sommerzeitumstellung Zwei Zeitzonen bei einer Sommerzeitumstellung

Zeitzonenunterstützung

Der Typ TIMESTAMPTZ kann mit einer geeigneten Erweiterung in Kalender- und Uhr-Bins eingeteilt werden. Die eingebaute ICU-Erweiterung implementiert alle Binning- und Arithmetikfunktionen mit den Zeitzonen- und Kalenderfunktionen der International Components for Unicode.

Um die zu verwendende Zeitzone festzulegen, laden Sie zuerst die ICU-Erweiterung. Die ICU-Erweiterung wird mit mehreren DuckDB-Clients vorinstalliert ausgeliefert (einschließlich Python, R, JDBC und ODBC), sodass dieser Schritt in diesen Fällen übersprungen werden kann. In anderen Fällen müssen Sie die ICU-Erweiterung möglicherweise zuerst installieren und laden.

INSTALL icu;
LOAD icu;

Verwenden Sie anschließend den Befehl SET TimeZone:

SET TimeZone = 'America/Los_Angeles';

Zeit-Binning-Operationen für TIMESTAMPTZ werden dann mit der angegebenen Zeitzone implementiert.

Eine Liste der verfügbaren Zeitzonen kann aus der Tabellenfunktion pg_timezone_names() bezogen werden:

SELECT
name,
abbrev,
utc_offset
FROM pg_timezone_names()
ORDER BY
name;

Sie finden auch eine Referenztabelle der verfügbaren Zeitzonen.

Kalenderunterstützung

Die ICU-Erweiterung unterstützt außerdem nicht-gregorianische Kalender mit dem Befehl SET Calendar. Beachten Sie, dass die Schritte INSTALL und LOAD nur erforderlich sind, wenn der DuckDB-Client die ICU-Erweiterung nicht mitliefert.

INSTALL icu;
LOAD icu;
SET Calendar = 'japanese';

Zeit-Binning-Operationen für TIMESTAMPTZ werden dann mit dem angegebenen Kalender implementiert. In diesem Beispiel berichtet der Teil era nun die Nummer der japanischen imperialen Ära.

Eine Liste der verfügbaren Kalender kann aus der Tabellenfunktion icu_calendar_names() bezogen werden:

SELECT name
FROM icu_calendar_names()
ORDER BY 1;

Einstellungen

Der aktuelle Wert der Einstellungen TimeZone und Calendar wird von ICU beim Start bestimmt. Sie können aus der Tabellenfunktion duckdb_settings() abgefragt werden:

SELECT *
FROM duckdb_settings()
WHERE name = 'TimeZone';
name value description input_type
TimeZone Europe/Amsterdam The current time zone VARCHAR
SELECT *
FROM duckdb_settings()
WHERE name = 'Calendar';
name value description input_type
Calendar gregorian The current calendar VARCHAR

Wenn Sie feststellen, dass Ihre Binning-Operationen sich nicht wie erwartet verhalten, prüfen Sie die Werte TimeZone und Calendar und passen Sie sie bei Bedarf an.