2 Punkte von GN⁺ 2024-08-16 | 1 Kommentare | Auf WhatsApp teilen

Erweiterung für hochpräzises Datum/Zeit

SQLite bietet grundlegende Datumsfunktionen, aber weil mehr Funktionalität benötigt wurde, wurde die hochpräzise Datum/Zeit-Erweiterung sqlean-time erstellt. Diese Erweiterung bietet eine strukturierte API und vielfältige Funktionen.

Hinweis. Das Hinzufügen einer Erweiterung zu SQLite ist sehr einfach. Man lädt die Datei herunter und führt einen einzigen Datenbankbefehl aus.

Konzepte

Diese Erweiterung verwendet zwei Werttypen: Zeit (Time) und Dauer (Duration).

  • Zeit (Time): Ein Paar aus Sekunden und Nanosekunden, das die Sekunden seit Zeit 0 (0001-01-01 00:00:00 UTC) und die Nanosekunden innerhalb der aktuellen Sekunde darstellt.

    • Zeiten können in einer internen Darstellung gespeichert werden, die Datumswerte Milliarden Jahre in die Vergangenheit und Zukunft mit Nanosekundenpräzision darstellen kann.
    • Zeiten können auch als Sekunden seit der Unix-Epoche (1970-01-01 00:00:00 UTC) gespeichert werden, ebenso in Millisekunden, Mikrosekunden oder Nanosekunden.
    • Zeiten werden immer in UTC gespeichert und verarbeitet, können aber in einen bestimmten Zeitzonen-Offset umgewandelt werden.
  • Dauer (Duration): Eine 64-Bit-Zahl in Nanosekunden, die Werte bis etwa 290 Jahre darstellen kann.

Erzeugen von Zeitwerten

  • Aktuelle Zeit:

    select time_fmt_iso(time_now());  -- 2024-08-06T21:22:15.431295000Z
    
  • Bestimmtes Datum/Uhrzeit:

    select time_fmt_iso(time_date(2011, 11, 18));  -- 2011-11-18T00:00:00Z
    select time_fmt_iso(time_date(2011, 11, 18, 15, 56, 35));  -- 2011-11-18T15:56:35Z
    

Extrahieren von Zeitfeldern

Es gibt Funktionen zum Extrahieren verschiedener Datums-/Zeitfelder:

select 'year  = ' || time_get_year(time_now());
select 'month  = ' || time_get_month(time_now());
select 'day   = ' || time_get_day(time_now());

Unix-Zeit

Funktionen zum Erzeugen von Zeitwerten aus Unix-Zeit (Zeit seit 1970-01-01 UTC):

select time_fmt_iso(time_unix(1321631795));  -- 2011-11-18T15:56:35Z

Funktionen zum Umwandeln von Zeitwerten in Unix-Zeit:

select time_to_unix(time_now());  -- 1722979335

Zeitvergleich

Funktionen zum Vergleichen von Zeitwerten:

select time_after(time_now(), time_date(2011, 11, 18));  -- 1
select time_before(time_now(), time_date(2011, 11, 18));  -- 0

Zeitoperationen

Funktionen zum Addieren einer Dauer zu einem Zeitwert:

select time_fmt_iso(time_add(time_now(), 24*dur_h()));  -- 2024-08-07T21:22:15.431295000Z

Dauerkonstanten:

  • dur_us() - 1 Mikrosekunde
  • dur_ms() - 1 Millisekunde
  • dur_s() - 1 Sekunde
  • dur_m() - 1 Minute
  • dur_h() - 1 Stunde

Rundung

Funktionen zum Runden von Zeitwerten auf die Präzision eines angegebenen Felds:

select 'original  = ' || time_fmt_iso(t.v) from t union all
select 'millennium = ' || time_fmt_iso(time_trunc(t.v, 'millennium')) from t;

Formatierung

Funktionen, die ISO-8601-Zeitstrings zurückgeben:

select time_fmt_iso(time_date(2011, 11, 18, 15, 56, 35, 666777888), 3*3600);  -- 2011-11-18T18:56:35.666777888+03:00

Dauerkonstanten

Funktionen, die gängige Dauern in Nanosekunden zurückgeben:

select dur_ns();  -- 1
select dur_us();  -- 1000

Danksagung

Diese Erweiterung wurde in C implementiert und auf Basis des Time-Pakets der Go-Standardbibliothek (BSD 3-Clause License) entworfen und umgesetzt.

Installation und Verwendung

  1. Neueste Release herunterladen
  2. In der SQLite-Kommandozeilenschnittstelle verwenden:
    sqlite> .load ./time
    sqlite> select time_now();
    

GN⁺-Zusammenfassung

  • Die Erweiterung sqlean-time fügt SQLite hochpräzise Datums-/Zeitfunktionen hinzu und ermöglicht vielfältige Zeitoperationen.
  • Zeit und Dauer können auf Nanosekundenbasis verarbeitet werden, was sehr präzise Zeitberechnungen ermöglicht.
  • Sie bietet verschiedene Funktionen für Zeitformatierung und -vergleich, sodass Entwickler sie leicht verwenden können.
  • Sie bietet deutlich mehr Funktionen als die Standard-Datumsfunktionen von SQLite und ist nützlich für Projekte, die komplexe Zeitoperationen benötigen.

1 Kommentare

 
GN⁺ 2024-08-16
Hacker-News-Kommentare
  • Frage, ob besondere Fälle von Zeitzonenänderungen und Diskontinuitäten der Ortszeit behandelt werden, wie sie von Jon Skeet dokumentiert wurden

  • Es ist besser, Datums-/Zeit- und Kryptografie-Bibliotheken nicht selbst zu bauen

    • Endlose Edge Cases können Probleme verursachen
    • Grund, bei neuen Bibliotheken skeptisch zu sein
  • Drei verschiedene Zeitdarstellungen/-größen sind interessant

    • Man fragt sich, für welche Anwendungsfälle Nanosekundenpräzision über Zeiträume von Milliarden Jahren nötig ist
    • Verwirrend ist, dass bei Nanosekundenpräzision nur ein Bereich von ±290 Jahren geboten wird
  • Es ist wichtig klarzustellen, ob vorzeichenbehaftete Ganzzahlen verwendet werden

    • Beim Lesen der Dokumentation wirkt es so, als könnten es vorzeichenbehaftete Ganzzahlen sein oder auch nicht
    • Wenn es vorzeichenbehaftete Ganzzahlen sind, könnte es mehrere Bitfolgen geben, die dasselbe Datum und dieselbe Uhrzeit darstellen
  • Es wäre schön, wenn SQLite3 ein erweiterbares Typsystem hätte

  • Es wird als sehr cool bewertet, wobei auf wichtige fehlende Funktionen von SQLite hingewiesen wird

  • Es wird argumentiert, dass Datenbanken Einheiten nachverfolgen sollten

    • Zum Beispiel sollte man angeben können, dass eine Zeitspalte float64-Sekunden darstellt
    • Die Datenbank sollte in der Lage sein, "2h" in 7200.0 Sekunden umzuwandeln und dies während eines Table Scans zu vergleichen
    • In der Vergangenheit wurde zwar einmal eine SQL-Datenbank für Spezialzwecke geschrieben, die so mit Einheiten umging, seitdem aber keine mehr gesehen
    • Sie sollte nicht nur Zeit, sondern alle Einheiten wie Masse, Volumen, Information, Temperatur usw. verarbeiten können
    • Man könnte der Datenbank beibringen, mathematisch sinnlose Operationen abzulehnen, um mathematische Fehler früh zu erkennen
  • Frage, was nützlicher ist: die Nanosekunden-Darstellung oder Jahre außerhalb des Nano-Bereichs

    • Da keine „exakte“ Wissenschaft betrieben wird, ist der Wert von Nanosekunden begrenzt
    • Es scheint häufiger nötig zu sein, historische Daten darstellen zu können
  • Vorschlag, Unix-Timestamps im Golang-Stil in Nanosekunden als vorzeichenbehaftetes int64 zu verwenden

    • Damit lassen sich bei Nanosekundenpräzision vielleicht keine Millionen von Jahren abdecken, aber es ist fraglich, ob das wirklich nötig ist
  • Es wird argumentiert, dass man den Ausdruck „Sekunden seit der Epoch“ nicht verwenden sollte, sofern er nicht exakt das bedeutet

    • Beispielabfrage: select time_sub(time_date(2011, 11, 19), time_date(1311, 11, 18));