-->

Datum und Zeit in MySQL

DateTime, Timestamp, Interval, ...

Fast jede Datenbank verwaltet u.a. auch Datum & Zeit-Daten.
Die Zeit vergeht zwar gleichmäßig, die Astronomie von Sonne, Mond und Erde gibt für derartige Daten jedoch relativ komplizierte Regeln vor.
Diese Seite zeigt einige der Probleme und Lösungen an dieser Schnittstelle zwischen Kalender, Zeit und Informatik.
SQL @ MySQL Standard Query Language
Datum & Zeit Verwaltung von Datum & Zeit in Datenbanken
Standards Greg. Kalender, Weltzeit UTC, Strings nach ISO-8601
Validierung Prüfung der manuellen Eingabe-Daten
Timestamp Zeitmarken zur Darstellung von Datum & Zeit
SQL-Funktion NOW
SQL-Funktionen UNIX_TIMESTAMP, FROM_UNIXTIME
Feld-Typen TIMESTAMP, INT
Rechnungen und Intervalle
DATETIME Standard Feld-Typ DATETIME
x
x
Aktuelle Daten Zeitmarke mit Funktionen NOW()
Bestandteile Zerlegung und Zusammensetzung von YEAR bis SECOND
CONVERT_TZ Umrechnung auf andere Zeitzonen
DATE_FORMAT Ausgabe formatierter Strings (Texte)
Verwandte Themen: Datum & Zeit, Timestamp, ISO-8601 Standard, ...
Programmiersprachen C/C++, Javascript, Perl, PHP, VBA (Access), ...
Betriebssysteme Linux, Windows (Konsole + Cygwin)

Datum & Zeit in Datenbanken

In fast allen Datenbanken werden auch Datum & Zeit - Daten verwaltet. Dabei sollen z.T. widersprüchliche Anforderungen erfüllt werden:
Die Lösung muss den bestehenden und den erwarteten Datum-Bereich abdecken (Erinnerung an das 'Jahr-2000-Problem' !).
Der Datenfluss von und zur Datenbank muss mit allen verwendeten und voraussehbaren Technologien und Daten-Formaten problemlos und rasch funktionieren.
Die Lösung soll einfache Rechnungen erlauben.
Die Interpretation der Daten muss weltweit eindeutig sein, unabhängig von Sprache, Kulturkreis und Zeitzone.

Das alles klingt recht trivial.
Der Teufel verbirgt sich - wie immer - im Detail ...

Modell "Struktur":

Datum und Zeit wird in Form einer Struktur von 6 einzelnen ganzen Zahlen gespeichert (Jahr, Monat, Tag, Stunden, Minuten, Sekunden, Differenz zur Weltzeit = TimeZone Offset in Stunden).
Das aktuelle Datum in Weltzeit (!) UTC lautet
{yyyy,mo,dd,hh,mi,ss,1}
Diese Variante bietet maximale Kompatibilität, hohe Geschwindigkeit und einen beliebig großen Datum-Bereich.
Ein besonderer Vorteil ist die Möglichkeit, unbekannte Datum-Teile mit 0 einzutragen (↓ Eingabe von Datum & Zeit).

Allerdings sind in dieser Variante keine Rechnungen möglich: Eine derartige Struktur kennt nicht die Logik von Stunden & Minuten, schon gar keinen Kalender.
Datum-Rechnungen benötigen daher einen hohen Aufwand an externer Software, und damit auch hohe Kosten.
Daher werden Datum & Zeit-Strukturen nicht als Speicherform verwendet, sehr wohl jedoch zum Transport von Daten.

Modell "Zeitstempel"

Datum und Zeit wird gemeinsam in einer Zahl codiert.
Das entspricht am besten der Natur der Zeit, die bekanntlich kontinuierlich abläuft.

Zum Rechnen genügen die 4 Grundrechnungs-Arten. Man braucht weder die Algorithmen zur Umrechnung von Sekunden, Minuten und Stunden (im uralten 60er-System) noch einen komplizierten Kalender mit ungleich langen Monaten, Schalttagen usw.
Das ist nicht nur praktisch sondern viel schneller !

Allerdings muss jedes Datum bei der Eingabe in die interne Zahl umgewandelt (codiert) und bei der Ausgabe wieder decodiert werden.

Jede Datenbank verwendet ein internes Format dieser Art zum Speichern von Datum & Zeit.
Meist wird ein → UNIX Timestamp verwendet, seltener das → Y1900-System von Microsoft oder der → Julianische Tag (JD).

Alle gängigen Zeitstempel verwenden zumindest intern die Weltzeit UTC (früher GMT).
Der UNIX-Timestamp
zählt die Sekunden seit 1970-01-01 00:00:00 in Weltzeit (UTC), d.h. ohne lokale Zeitzone oder Sommerzeit.

Mit ganzen Zahlen lässt sich besonders rasch rechnen.
Daher wird der ganzzahlige UNIX-Timestamp von allen Datenbanken und von jeder modernen Programmiersprache unterstützt.

Der Timestamp wird als ganze Zahl mit 32 Bit (INTEGER) formuliert.
1 Tag entspricht der Zahl 24*60*60=86400,   1 Stunde 60*60=3600,   1 Minute 60, usw.
Der aktuelle UNIX-Timestamp in Sekunden ist
uts = 0000000000

Texte (Strings)

Alle Datenbanken bieten die Möglichkeit, Datum- und Zeit-Daten in Form von Strings (Texten) ein- und auszugeben. Das erlaubt den Austausch praktisch beliebig formatierter Daten.
Allerdings stellen Datum-Strings gleichzeitig einen gefährlichen Schwachpunkt dar: Die meisten älteren Formate sind historisch gewachsen, daher selten einheitlich, von der lokalen Sprache und Kultur abhängig und manchmal so chaotisch wie die vielen unterschiedlichen US-Datum und Zeit-Formate.
"mo/dd/yy hh:mi:ss"
Die Angabe der Zeitzone ist in kleinen Kultur- und Wirtschaftsräumen nicht notwendig und fehlt daher meist, sogar in der heutigen globalisierten Welt.

Daher muss die Software meist Annahmen (!) treffen, um eintreffende Datum-Strings richtig zu verstehen.
Solche Risken sind für wichtige Daten inakzeptabel. Daher sollte durch zusätzliche (meist aufwändige) Maßnahmen garantiert werden, dass die Datum-Strings eindeutigen Regeln folgen, am besten dem weltweiten Standard → ISO-8601.
"yyyy-mo-dd hh:mi:ss"

Tipp: So bald wie möglich eine saubere Trennung herbeiführen:
Strings (Texte) sind für Menschen geeignet und eine Aufgabe der User Interface Programme.
In die Datenbank gehören keine Datum & Zeit-Strings sondern nur sichere, eindeutige Daten wie z.B. Timestamps.

Datum & Zeit Standards

International Standards Organisation Standards

haben bei der Verwaltung von Daten besonders große Bedeutung.
Datenbank-Projekte haben eine wesentlich größere Lebensdauer als z.B. Software.
Datenbanken werden meist von zahlreichen AnwenderInnen verwendet, teilweise aus unterschiedlichen geografischen und sprachlichen Gebieten, üblicherweise auch mit unterschiedlicher Hardware und Software.
Die strikte Einhaltung internationaler Standards sichert die Einheitlichkeit und Eindeutigkeit der Daten.

Kalender

Weltweit anerkannt ist mittlerweile der Gregorianische Kalender von 1582. Das hat einen Grund: Dieser Kalender bietet den besten Kompromiss zum Umgang mit den Umlauf-Zeiten von Erde und Mond und der Rotationsdauer der Erde, die sich nicht ganzzahlig zueinander verhalten.

Allerdings hat es je nach nationalem Egoismus bis ins 20. Jahrhundert gedauert, diesen Standard einzuführen.
Nur Exoten leisten sich heute noch andere Kalender und müssen die Daten-Umrechnung entsprechend bezahlen.
Zeit ist ein kritischer Faktor, der in vielen kleineren Betrieben und Organisationen noch vernachlässigt wird - Das kann teuer werden.

Der einheitliche internationale Zeit-Standard ist die Weltzeit UTC (früher GMT). In Zeiten der Globalisierung sollten Server und Datenbanken nur UTC verwenden. Andernfalls müsste man zu allen Daten zusätzlich die jeweilige Zeitzone sowie Sommer/Winterzeit verwalten.
In Mitteleuropa (MEZ, CET) gilt
UTC = Normalzeit - 1 Stunde
UTC = Sommerzeit - 2 Stunden
Wenn Zeit-Differenzen eine Rolle spielen, dann muss unbedingt die Weltzeit UTC verwendet werden, die weder Zeitzonen noch Sommerzeit (daylight savings) kennt.

Strings

Nur der Standard ISO-8601 für Datum & Zeit-Strings garantiert eine weltweit absolut eindeutige Interpretation. Insbesondere die Büro-Software des IT-Marktführers neigt leider dazu, diesen Standard durch eine Flut weltweit unterschiedlicher Formate zu unterlaufen.

Die aktuellen Daten in Weltzeit UTC nach ISO-8601:
yyyy-mo-dd hh:mi:ss
yyyy-mo-dd hh:mi:ss

Details zum Thema Datum & Zeit sowie zum Standard ISO-8601.

Synchronisation (NTP)

Die interne Uhr des Datenbank-Server-PC muss zumindest auf einige Sekunden genau eingestellt sein, möglichst auf Weltzeit UTC.
Tests von Servern auch prominenter Organisationen zeigen Abweichungen bis zu einigen Stunden !
Die Synchronisation mit einem Zeitserver ist einfach und kostenlos - Man muss es aallerdings auch tun.
Wenn Datenbank-Server und Webserver auf getrennten PC laufen, dann müssen ihre internen Uhren unbedingt synchron laufen.

Details zu den Themen Synchronisation und NTP

Eingabe und Validierung von Datum & Zeit

Die Eingabe von Datum & Zeit-Daten durch menschliche AnwenderInnen ist ein besonderer Schwachpunkt vieler Datenbanken.

Eingabe-Fehler

An dieser Stelle gelangen zahlreiche Fehler unbemerkt in die Daten.
Ein sorgfältige Validierung (Kontrolle der Daten vor dem Speichern) ist unumgänglich !

Unbekannte Daten:

Es kommt relativ häufig vor, dass Daten zumindest zum Zeitpunkt der ersten Eingabe nur teilweise oder gar nicht bekannt sind. Eine gut konfigurierte Datenbank bietet für diesen Fall Lösungen an.

Kalender

Es hat große Vorteile, an Stelle eines Eingabe-Felds einen kleinen Kalender anbieten. Die AnwenderInnen schätzen die bessere Übersicht, und die einfache und schnelle Bedienung mit der Maus.
Die Datenbank erhält Daten garantiert ohne Eingabe-Fehler - ein fast unbezahlbarer Vorteil !
Das Beispiel arbeitet mit Javascript - d.h. ohne Belastung des Webservers !
Erzeugung eines SQL-Befehls mit einem Javascript-Kalender:
(Klicken sie einen Kalendertag)
 

Details zur Javascript-Programmierung des Kalenders.

Validierung

Bei jeder Art von Daten sollte vor dem Speichern überprüft werden, ob sie zulässig und sinnvoll sind. Bei Datum & Zeit ist die Validierung noch wichtiger.

Man prüft z.B., ob alle benötigten Bestandteile eingegeben wurden und ergänzt fehlende Teile durch Standard-Werte. Danach wird geprüft, ob die Werte zulässig sind, z.B. 1<=Monat<=12

Um Missverständnisse sicher auszuschließen ist es besser, unerlaubte Werte zurückzuweisen als sie richtigzustellen.

Der Prozess der Validierung wird so weit wie möglich auf den Client-PC verlagert: So kann ein menschlicher Anwender seine Eingabe-Daten auch mehrmals hintereinander ausbessern, ohne das Netzwerk und vor allem den Server zu belasten.
Javascript
In dynamischen Webseiten muss die erste und wichtigste Validierung mit Javascript erfolgen. Das Programm sollte Eingabe-Daten nur dann absenden, wenn sie absolut fehlerfrei sind. So wird der Client-PC sinnvoll eingesetzt und es gelangen keine ungeprüften Daten zum Server.

User Interface
(Java, Perl, PHP, Python, ...) Diese Programme sollten nur bereits geprüfte Daten erhalten. Als Schutz gegen Missbrauch führt man trotzdem eine Prüfung durch, die jedoch kaum mehr Daten zurückweist und rasch abläuft.

SQL
Die letzte Sicherung gegen Daten-Fehler ist der SQL-Server. Sie sollte jedoch nicht in Anspruch genommen werden. SQL-Fehler nimmt man zum Anlass, die vorgelagerte Validierungs-Software zu verbessern.

Fehlende Daten-Teile:

Die Häufigkeit, mit der (teilweise) unbekannte Daten auftreten, wird fast immer unterschätzt. Wenn eine Software bedingungslos nur die Eingabe vollständiger Daten zulässt, dann zwingt man die AnwenderInnen, auch dann 'irgendwelche' Daten einzugeben, wenn diese unbekannt sind.

Das zeigt sich meist an einer Häufung ungewöhnlicher Daten wie z.B. dem 1.Jänner eines Jahres. Wenn man die AnwenderInnen nicht unterstützt, erhält man jedoch viele verschiedene unkoordinierte Reaktionen, und kann unvollständige Daten kaum wiederfinden.

Einfache Maßnahme:
Man einigt sich in einem Betrieb auf eine einheitliche Reaktionsweise: Bei unbekannten Daten wird z.B. der 2000-01-01 eingegeben...
Aufwändiger:
Unbekannte Daten werden mit einem zusätzlichen Datenbank-Feld markiert oder kommentiert.
In jedem Fall sollte man eine Möglichkeit suchen, unvollständige Daten wieder zu finden und bei Bedarf nachträglich zu korrigieren.

Aktuelle Daten

MySQL stellt einige Funktionen zur Verfügung, welche die aktuelle Systemzeit liefern.
Diese Funktionen werden verwendet, um Felder der Typen DATETIME, TIMESTAMP, DATE, TIME auf die Systemzeit zu setzen.
Dabei wird die Systemzeit des DB-Servers verwendet.
Dieser ist im Idealfall auf die Weltzeit UTC gestellt. Andernfalls müsste man zusätzlich die Zeitzone und Sommerzeit/Winterzeit verwalten.
Die SQL-Funktion NOW() liefert das aktuelle Datum und die aktuelle Zeit.
NOW()   verwendet die System-Uhr des Datenbank-Servers - Nicht jene des Clients !
Die gelieferten Daten enthalten bei korrekter Konfiguration des Servers die Zeit als → Weltzeit (UTC).
Zur Anzeige werden diese Daten jedoch (je nach Version) in die lokale Zeitzone umgewandelt.
Tipp: Verwenden sie immer die Funktion NOW() für die aktuellen Datum & Zeit-Daten, denn Felder anderer Typen (DATE, TIME, TIMESTAMP) entnehmen daraus den jeweils zutreffenden Anteil.
Ausgabe von Datum und Zeit beim Laden dieser Webseite:
SELECT NOW();
Ausgabe:   yyyy-mo-dd hh:mi:ss

INSERT into test SET dt=NOW();
Erzeugt einen neuen Datensatz in der Tabelle test und trägt die aktuellen Datum & Zeit-Daten in das Feld dt ein.

UPDATE test SET dt=now() WHERE pk=;
Schreibt das aktuelle Datum in das Feld (Spalte) dt des Datensatzes (Zeile) pk= (Primär-Schlüssel   pk) der Tabelle test
Testen sie (z.B. mit einem kleinen Programm in → Perl oder → PHP), ob ihr Webserver die gleiche Zeit verwendet wie ihr Datenbank-Server.
<?php
print strftime('%Y-%m-%d %H:%M:%S',time());
?>
Funktion CURDATE() liefert das aktuelle Datum ohne Uhrzeit. Auf Felder der Typen DATETIME, TIMESTAMP angewendet, wird deren Zeit auf 00:00:00 gesetzt.
Verwenden sie im Zweifel besser die Funktion NOW()
SELECT CURDATE();
Ausgabe:   yyyy-mo-dd
Funktion CURTIME() liefert die aktuelle Uhrzeit ohne Datum. Sie sollte nur auf Felder der Type TIME angewendet werden.
Verwenden sie im Zweifel besser die Funktion NOW().
SELECT CURTIME();
Ausgabe:   hh:mi:ss
(Zeit am Datenbank-Server beim Laden dieser Webseite)

Bestandteile (YY-MO-DD hh:mi:ss)

Zerlegung von Datum & Zeit

Einige Funktionen bieten die Möglichkeit, ganzzahlige Bestandteile aus einem Feld vom Typ DATETIME zu entnehmen.


Fatal error: Call to undefined function get_mysql_scalar() in /home/topsoft.at/www.topsoft.at/pstrainer/entwicklung/sql/datim/sql_date_time.php on line 879