Open j3nsch opened 3 years ago
Spricht denn etwas dagegen, dass OPUS-intern ausschließlich mit UTC±0 / GMT gearbeitet wird (und auch die Datenspeicherung mit dieser Einstellung erfolgt)? Die Konvertierung in die Zeitzone des Anwenders (Zeitzone des Serverbetreibers oder User-Agents?) würde dann erst beim Rendering in HTML/XML/JSON erfolgen. Ganz sauber wäre es eigentlich, wenn alle Zeitangaben um die Zeitzone ergänzt werden (an welchen Stellen geben wir eigentlich Zeitangaben aus?). Bislang war das alles vermutlich kein Thema, weil es einen starken Fokus auf die deutsche Anwendercommunity gab/gibt.
Ja, kompliziertes Thema, dass ja auch nicht zum ersten Mal auftaucht. Deshalb hat die Opus\Date
Klasse ja auch 56 Tests.
Egal, wenn wir intern mit UTC arbeiten, dann kann man das sicherlich bei der Anzeige an die lokale Zeit anpassen. Vermutlich vorzugsweise die Zeit des Servers und nicht des Browsers. Gerade bei dieser Datenbankabfrage gibt es dann aber immer noch das Problem, dass der Check dann mit UTC arbeitet und damit unter Umständen bis zu 12 (?) Stunden daneben liegt, relativ zur Zeitzone des Servers. Es geht eben nicht nur um die Anzeige. Die Probleme treten bei der Verarbeitung, bei den Vergleichen zwischen Zeit & Datumsangaben auf.
Wenn die Tests ausschließlich mit Zeitangaben in UTC±0 formuliert sind, dann sollte es keine Abweichungen geben, oder? Damit sind die Tests dann vollständig unabhängig von der Zeiteinstellung des Servers / der VM, auf dem/der die Tests ausgeführt werden.
Was man prinzipiell auch noch ansehen müsste: wenn Zeitvergleiche mit Parametern direkte auf DB-Ebene (SQL) erfolgen, dann müssen die zu vergleichenden Zeitwerte eine identische Präzision haben, z.B. beide in Microsekunden oder Millisekunden aufgelöst sein. Sonst könnte es rundungsbasierte Ungenauigkeiten geben.
Kannst Du gerade überblicken, an welchen Stellen in OPUS tatsächlich Zeitangaben mit Uhrzeiten verwendet werden? Die meisten zeitbasierten Metadatenfelder speichern nur das Datum (ohne Zeitanteil). Mir fallen eigentlich nur die internen Felder (server_date_modified usw.) ein, die Zeitanteile umfassen. Wenn das so ist, dann sollte ausschließlich die Zeitzone des Servers (und nicht des anfragenden Clients) berücksichtigt werden.
Beim aktuellen Problem, handelt es sich ja um einen Vergleich innerhalb der Datenbank mit SQL. Alles andere läuft über Opus_Date
und da sind mit im Augenblick keine Probleme bekannt. Es wurde ja schon mal drüber nachgedacht und es wurden dafür die vielen Tests geschrieben. Was damals nicht bekannt war, ist dieser in SQL durchgeführte Vergleich. Das wurde übersehen. Ich würde die Lösungsansätze daher auf genau dieses Problem begrenzen wollen. Natürlich können bei Bedarf Anpassungen zentral in der Date-Klasse vorgenommen werden.
Den Test an sich kann man mit einer Beschränkung auf UTC vermutlich fixen. Die eigentliche SQL-Abfrage funktioniert aber auch dann nur für GMT 100% korrekt.
Das Embargo-Date ist ja ein Datum, dass letztendlich in jeder Zeitzone eine andere konkretes Zeitfenster bedeutet. In der Date-Klasse wird das Problem umgangen, in dem nur Datum mit Datum verglichen wird. Ich weiß nicht, ob das mit SQL-Bordmitteln, bei diesem Vergleich in der Datenbank möglich ist. Man könnte für genau diesen Anwendungsfall, das Datum aus ServerDateModified
heraustrennen oder duplizieren.
Oder etwas längerfristiger könnte und vermutlich sollte man diese Abfrage über den Index beantworten und dort die notwendigen Felder gleich passend befüllen. Ich vermute, dass ist der sinnvollste Ansatz, da der DocumentFinder
in Zukunft sowieso nicht alle Suchen mit SQL durchführen können wird. Im Augenblick fangen wir aber nicht auch noch an den Index-Umzubauen, obwohl das jetzt vermutlich eine überschaubare Ergänzung wäre.
Ich habe gerade eine Entwicklungsinstanz parat, aber kannst Du mal nachsehen, ob auf der Ebene der MySQL-Datenbank bei den Spalten mit Zeitangaben auch die Zeitzone explizit in der Datenbank gespeichert wird. Dann wären die Angaben eindeutig und bei einem Vergleich muss "nur" darauf geachtet werden, dass die beiden zu vergleichenden Zeitangaben in der gleichen Zeitzone vorliegen (ggf. vorher Konvertierung durchführen). Vielleicht hat MySQL sogar eine eingebaute Funktion, die das übernimmt?
Wir könnten die Date
-Funktion verwenden. Müsste man mal ausprobieren.
SELECT * FROM table WHERE DATE(timestamp) = '2012-05-25'
Und ja, die Zeitzone wird mit abgespeichert. Interessant würde es werden, wenn ein Server in eine andere Zeitzone umgezogen wird, und dann gemischte Zeitzonen in der Datenbank existieren. Das ist aber ein theoretisches Problem, mit dem wir uns im Augenblick nicht befassen werden. Es gibt wichtigeres.
Hab den nächtlichen Build jetzt auf 23 Uhr verlagert, in der Hoffnung den Fehler dadurch provozieren zu können. Wenn das klappt, kommt der Fix morgen dazu, um zu schauen, ob es in der nächsten Nacht funktioniert.
Ich habe es noch nicht geschafft, den nächtlichen Build so zu legen, dass der Fehler immer auftritt. Muss wohl doch noch mal Zuhause nachts ran oder das Problem ist doch noch anders als gedacht.
Der folgende Test schlägt fehl, wenn er in der Nähe von Mitternacht läuft.
DocumentFinderTest::testFindDocumentsWithExpiredEmbargoDateForUpdatingServerDateModified
Das Problem entsteht dadurch, dass Zeitstempel in der Datenbank mit Datumsangaben verglichen werden. Die Funktion
setEmbargoDateBeforeNotModifiedAfter
desDocumentFinder
konstruiert die entsprechende Abfrage. Bei der Funktion geht es darum zu ermitteln, bei welchen Dokumenten der Wert vonServerDateModified
aktualisiert werden muss, damit die Dokument erneut von der DnB erfasst werden müssen. Durch die Aktualisierung werden die Dokumente Teil des nächsten OAI-Exports.Der Zeitstempel berücksichtigt die Zeitzone, z.B.
+02:00
, die reine Datumsangabe wird vermutlich als Universal Time interpretiert. Auf jeden Fall ergibt sich daraus zwei Stunden in denen der Test nicht funktioniert.Der Test sollte zu jeder Zeit durchlaufen. Dafür muss die eigentlich Funktionalität gefixt werden. Beim Vergleich von Datumsangaben bekommt man schnell Kopfschmerzen. Was muss passieren?
Wir müssen davon ausgehen, dass die Zeitstempel in der Datenbank der lokalen Zeitzone entsprechen. Die Datumsangabe mit der verglichen werden soll, müsste in einen Zeitstempel für die lokale Zeitzone umgewandelt werden, damit die beiden Zeitangaben korrekt miteinander verglichen werden können. Die Datumsangabe ist das
EmbargoDate
, dass nur als String gespeichert wird. Wenn man hier einen vollständigen Zeitstempel verwenden will, müsste der Wert beim Lesen und Speichern umgewandelt werden.Gibt es eine einfachere Lösung? Egal in welcher Zeitzone der Server steht, wenn lokal das Embargo abgelaufen ist, sollte das Dokument ab Mitternacht abrufbar sein.