Erstellt vor 3 Jahren
Geschlossen vor 3 Jahren
#1871 closed Fehler (fixed)
Datumsformat dd-mm-yy verursacht Fehler in Rose::DB::Object
| Erstellt von: | fobermayr | Verantwortlicher: | t.heck@… |
|---|---|---|---|
| Priorität: | normal | Meilenstein: | 3.0.0 |
| Komponente: | kivitendo ERP | Version: | 2.7.0 |
| Schweregrad: | normal | Stichworte: | Lager, Einlagern |
| Beobachter: |
Beschreibung
ICh habe in der Kivitendo Demo ein Lieferantenauftrag des Lieferanten A-Diverses mit der Position Artikelnummer 701 ins Lager einbuchen wollen. Bei dem extra geöffneten Fenste rhabe ich lediglich die Menge 1 angegeben und auf weiter gedrückt. Nach Erneuerung wollte ich das Einlagern.
Folgender Fehler ist erschienen:
Warehouse transfer error: do_transaction() failed - Could not add bin object - Invalid timestamp: 'Wed 03 Jun 14:43:33.390196 2009' at /usr/share/perl5/Rose/DB/Object/MakeMethods/Generic.pm line 6090
at /usr/share/perl5/Rose/DB/Object.pm line 528
at SL/WH.pm line 129
Auch mit einem anderen Artikel (Nummer: 1006) passierte der selbe Fehler.
Änderungshistorie (8)
comment:1 Geändert vor 3 Jahren durch m.bunkus@…
comment:2 Geändert vor 3 Jahren durch m.bunkus@…
Weitere Erkenntnisse:
Auch ein Update von Rose::DB und Rose::DB::Object auf dem Server haben nicht geholfen.
Artikel 701 in der Demo ist eine Dienstleistung. Zum Einen lässt Kivitendo momentan zu, dass DLs eingelagert werden, zum Anderen bemängelt es sogar, dass ein Lieferschein gemischt DLs/Waren unvollständige Einlagerinformationen beinhaltet, wenn man die DLs auf Einlagermenge 0 belässt. Aber auch nur mit Waren tritt derselbe Fehler auf.
comment:3 Geändert vor 3 Jahren durch m.bunkus@…
Weiteres Debuggen liefert die Ursache:
Kivitendo setzt beim Verbindungsbeginn das Datumsformat, das die Anwendung mit dem Server beiderseitig sprechen soll, anhand des Datumsformats, das beim Benutzer eingestellt ist. Rose::DB::Object muss nun diese Formate parsen. Dazu kommt das Modul DateTime::Format::Pg zum Einsatz.
In der Demo ist als Datumsformat dd-mm-yy eingestellt. Dafür wird bei PostgreSQL das Datumsformat auf POSTGRES, EUROPEAN gesetzt:
SET DATESTYLE = POSTGRES, EUROPEAN;
Das erkennt aber DateTime::Format::Pg nicht.
Workaround: Datumsformat auf das deutsche (dd.mm.yy) oder das ISO-Format (yyyy-mm-dd) setzen.
comment:4 Geändert vor 3 Jahren durch m.bunkus@…
- Status von new nach accepted geändert
- Zusammenfassung von Fehler bei Einlagerung ins Lager nach Datumsformat dd-mm-yy verursacht Fehler in Rose::DB::Object geändert
comment:5 Geändert vor 3 Jahren durch m.bunkus@…
Nun habe ich auch die tatsächliche Ursache.
Wird als Datumsformat dd-mm-yy oder mm-dd-yy eingestellt, so wird im Hintergrund das Datumsformat von PostgreSQL auf POSTGRES, EUROPEAN bzw. POSTGRES, US eingestellt. Damit sind die Ergebnisse des SQL-Schlüsselwortes current_date das, was man Erwartet, z.B. 13-06-2012 für die deutsche Variante.
Leider ist das Ergebnis der SQL-Funktion now() in diesem Falle deutlich unschöner, nähmlich z.B. Wed 13 Jun 13:41:33.75281 2012 CEST. Man beachte, dass dort englische Abkürzungen von Wochentag und Monat enthalten sind. In anderen Locales sind die entsprechend anders.
Nun kommt Rose::DB::Object ins Spiel. Sobald RDBO ein Objekt aus der Datenbank lädt, werden alle Spalten vom SQL-Typ timestamp in eine Instanz eines Perl-Objektes DateTime umgewandelt. Dazu kommt das Perl-Modul DateTime::Format::Pg zum Einsatz, das beinahe alle von PostgreSQL unterstützten Formate parsen und ausgeben kann -- bis auf eben das DATESTYLE = POSTGRES-Format, vermutlich wegen der Unportierbarkeit der lokalisierten Monatsnamen.
Da in Zukunft immer mehr Code RDBO nutzen wird, wird das ein noch viel größeres Problem, als es jetzt ist.
Lösungsmöglichkeiten sehe ich eigentlich nur eine, die ich wirklich mag. Hier alle Möglichkeiten, die ich generell sehe:
- Wir posten einen Bugreport gegen das Modul DateTime::Format::Pg und bitten darum, dass das Parsen und Formatieren von POSTGRES-Style-Datumswerten unterstützt wird. Die Wahrscheinlichkeit, dass das jemals passieren wird, sehe ich bei unter 20%, dass das bald geschieht bei eher 0%.
- Wir übernehmen DateTime::Format::Pg in den lokalen modules/override-Ordner und implementieren das Parsen und Formatieren selber. Das aber lokalisierungsunabhängig hinzugekommen, ist nicht nur nervig, sondern echt schwer und fehlerträchtig.
- Wir entfernen den Support für die Datumsformate dd-mm-yy und mm-dd-yy aus dem Programm.
Von diesen Variante bevorzuge ich klar Nr. 3. Zum Einen, weil 1. und 2. so lächerlich unwahrscheinlich sind, und noch viel mehr, weil das ISO-Datumsformat (yyyy-mm-dd) ursprünglich den Bindestrich als Trennzeichen verwendet hat, weil dieser in keinem anderen Format bisher verwendet wurde. Man wollte damit jegliche Verwirrung (was kommt zuerst? Tag oder Monat?) vermeiden und ein eindeutig parsbares Format schaffen. Dann solche Abarten wie dd-mm-yy auch selber noch zu unterstützen misfällt mir eh schon seit langem.
comment:6 Geändert vor 3 Jahren durch m.bunkus@…
Klarstellung. Die SQL-Funktion now() hat verhältnismäßig wenig mit dem Problem zu tun. Wichtiger ist, dass PostgreSQL generell alle Spalten vom SQL-Typ timestamp in der oben beschriebenen Art formatiert, wenn es mittels DATESTYLE = POSTGRES, ... dazu veranlasst wird. Das betrifft z.B. die ganzen Spalten itime und mtime, die in fast allen Kivitendo-Tabellen verwendet werden, um die Zeitpunkte des Einfügens bzw. der letzten Änderung zu speichern. Werden bei diesem eingestellten Datumsformat solche Zeilen mit RDBO ausgelesen, so fliegt das Ganze in die Luft.
comment:7 Geändert vor 3 Jahren durch m.bunkus@…
- Meilenstein auf 3.0.0 gesetzt
- Status von accepted nach assigned geändert
- Verantwortlicher von m.bunkus@… nach t.heck@… geändert
Da niemand eine Meinung hierzu hat, entscheide ich mich nun für Lösung 3: wir entfernen die Datumsformate "dd-mm-yy" und "mm-dd-yy" aus dem Programm.
comment:8 Geändert vor 3 Jahren durch Thomas Heck <theck@…>
- Lösung auf fixed gesetzt
- Status von assigned nach closed geändert

Ich kann es in der Demo-Installation reproduzieren, nicht aber auf meiner Entwicklungsinstallation.
In beiden Fällen sind die verwendeten PostgreSQL-Cluster mit allen Locales == de_DE.UTF-8 konfiguriert. RDBO-Versionen sind leicht unterschiedlich.