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 ZONEgibt, werden externe Spalten mit Nanosekundengenauigkeit und SemantikWITH TIME ZONE, z. B. Parquet-Timestamp-Spalten mitisAdjustedToUTC=true, inTIMESTAMP WITH TIME ZONEumgewandelt 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.123456789SELECT TIMESTAMP '1992-09-20 11:30:00.123456789';1992-09-20 11:30:00.123456SELECT TIMESTAMP_MS '1992-09-20 11:30:00.123456789';1992-09-20 11:30:00.123SELECT TIMESTAMP_S '1992-09-20 11:30:00.123456789';1992-09-20 11:30:00SELECT TIMESTAMPTZ '1992-09-20 11:30:00.123456789';1992-09-20 11:30:00.123456+00SELECT TIMESTAMPTZ '1992-09-20 12:30:00.123456789+01:00';1992-09-20 11:30:00.123456+00DuckDB 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.
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:
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:
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_offsetFROM 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 nameFROM 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
TimeZoneundCalendarund passen Sie sie bei Bedarf an.