# Datumsformat aus MySQL ändern



## didi577 (16. Feb 2017)

Hi,

ich bekomme aus eine MySQL DB ein Datum das in der Combobox im Format yyyy-MM-dd angezeigt wird. Das will ich in dd.MM.yyyy ändern. Bislang sah die select Abfrage so aus:

```
SELECT DISTINCT f.datum...
```
habe es in:

```
"SELECT DISTINCT DATE_FORMAT(f.datum, '%d.%m.%Y') AS datum
```
 geändert.Klappt auch. Jetzt funktionieren meine Abfragen jedoch nicht mehr. Er zeigt mir 0 Datensätze an. Wo muss ich nachjustieren?
Gibt es eine andere Möglichkeit die Ansicht rein auf der GUI Ebene zu ändern?


----------



## Joose (16. Feb 2017)

Die Daten sollten einfach als Datum geladen werden in welchem Format ist egal. Wo du sie dann anzeigen willst bzw. in eine Datei schreiben willst ist es dann wichtig(er) welches Format die Daten haben. --> Umformatieren erst bei der Anzeige, dazu solltest du das Datum in einem Date Objekt haben.


----------



## didi577 (16. Feb 2017)

ich bin mir nicht sicher aber ich würde die Wandlung im ActionListener der Combobox vornehmen. Gleich nachdem die Daten geladen wurden. Hab mal angefangen:

```
SimpleDateFormat formater = new SimpleDateFormat("dd-MM-yyyy");
               ??? = formater.format(boxDatum.getSelectedItem());
```
gewandelt soll der Wert in der BoxDatum werden
ich komme maximal zur Meldung java.lang.IllegalArgumentException: Cannot format given Object as a Date
ist der Weg richtig?


----------



## Flown (16. Feb 2017)

Was bekommst du aus deiner boxDatum denn für ein Typ zurück? Offensichtlich kein Date.


----------



## didi577 (16. Feb 2017)

ist noch ein String


----------



## VfL_Freak (16. Feb 2017)

didi577 hat gesagt.:


> ist noch ein String


eben ... und was erwartet _*SimpleDateFormat *_als Parameter ???


Spoiler: erst überlegen :-)



https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html



Gruß Klaus


----------



## Harry Kane (16. Feb 2017)

Das sieht wieder so aus, als würde da am Ende eine vonhintendurchdiebrustinsauge-Lösung rauskommen. *schauder*
Lass die ganze Hin-und Herkonvertierung zwischen Strings und Objekten anderen Typs sein. Wie eine JComboBox ein Object darstellt, kann über einen ListCellRenderer beeinflusst werden. Sofern bei einer JComboBox kein ListCellRenderer gesetzt ist, wird eine Instanz von DefaultListCellRenderer verwendet, die einfach toString() auf dem Object aufruft. Du könntest DefaultListCellRenderer wie folgt erweitern:

```
public class DateCellRenderer extends DefaultListCellRenderer {
    private SimpleDateFormat format = new SimpleDateFormat("dd.MM.yy");
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        if (comp instanceof JLabel) {
            JLabel label = (JLabel) comp;
            if (value instanceof Date) {
                String text = format.format((Date) value);
                label.setText(text);
            }
        }
        return comp;
    }
}
```


----------



## didi577 (16. Feb 2017)

Danke für deinen Code!!!! Habe eine Klasse eröffnet und den Code eingefügt. Habe in der Klasse wo ich die Combobox initialisiere:

```
boxDatum.setRenderer(new DateCellRenderer());
```
 eingefügt. Das Datum wird immer noch im alten Format angezeigt. Habe die Zeile nach der Initialisierung eingefügt. Was muss ich noch beachten?


----------



## Harry Kane (16. Feb 2017)

didi577 hat gesagt.:


> Was muss ich noch beachten?


Grundlagen, Grundlagen, Grundlagen.
Was soll man mit der einen, vollkommen aus dem Kontext gerissenen Zeile anfangen? Ich traue dir mittlerweile auch nicht mehr zu, ein Fehlverhalten richtig zu beschreiben, so wie in deinem JPanel per mail verschicken thread, wo du zunächst eine Diskrepanz zwischen dem Inhalt eines html und einer JTable bemerkt zu haben glaubtest, und dir erst später aufgefallen ist, dass die JTable offenbar nicht mehr den erwarteten Inhalt hat und mit dem html übereinstimmt.
Gehen wir aber einfach mal davon aus, dass sich an der Anzeige in JComboBox tatsächlich nichts geändert hat. Dafür gibt es nicht viele Möglichkeiten. Bzw. eigentlich nur eine, nämlich das der "value instanceof Date" Test fehlschlägt. Weiter oben hast du ja erwähnt, dass du aus deiner Datumsbox Strings zurückbekommst, also sind welche drin. Und dann liefert die instancof Prüfung false zurück.
Damit du die DateCellRenderer Klasse nutzen kannst, musst du die select-Abfrage so schreiben, dass die Spalte als Datum abgefragt wird (das sollte eigentlich automatisch passieren, sofern die Spalte vom Typ DATE, TIME oder TIMESTAMP ist), und dann noch aus dem result set den Wert als Datum rausholen (resultset.getDate(int columnindex) oder resultset.getDate(String columnname)) und die Werte dann als Date-Instanzen in die Datumsbox packen.


----------



## didi577 (17. Feb 2017)

du wirst es mir wahrcheinlich nicht galauben, aber das "value instanceof Date" habe ich registriert und natürlich mit meinem Problem in Verbindung gebracht. Ich habe auch in meiner MySQL Klasse an entsprechender Stelle Lösungen probiert. Ich habe das nur nicht geschrieben. Mein Fehler.
Die Abfrage sieht jetzt so aus:

```
HashMap<String, Integer> ladenAuswertung(DefaultComboBoxModel boxDozentM,
           DefaultComboBoxModel boxKursM, DefaultComboBoxModel boxOrtM,
           DefaultComboBoxModel boxDatumM, String sql, String spalte) {

       HashMap<String, Integer> map = new HashMap<>();

       PreparedStatement pst = null;
       ResultSet rs1 = null;

       try {
           String dozent = boxDozentM.getSelectedItem().toString();
           String kurs = boxKursM.getSelectedItem().toString();
           String ort = boxOrtM.getSelectedItem().toString();
           Date datum = boxDatumM.getSelectedItem();
           pst = con.prepareStatement(sql);
           pst.setString(1, dozent);
           pst.setString(2, kurs);
           pst.setString(3, ort);
           pst.setDate(4, datum);
           rs1 = pst.executeQuery();

           while (rs1.next()) {

               spalte = rs1.getString(1);
               int count = rs1.getInt(2);
               map.put(spalte, count);
               datum = rs1.getDate(4);
           }

       } catch (SQLException e) {
           e.printStackTrace();

       } finally {
           if (rs1 != null && pst != null) {
               try {
                   rs1.close();
                   pst.close();
               } catch (SQLException e) {
                   e.printStackTrace();
               }
           }
       }

       return map;
   }
```
in der while Schleife habe ich     datum = rs1.getDate(4); und für das befüllen der box     Date datum = boxDatumM.getSelectedItem(); und pst.setDate(4, datum);
allerdings meckert er noch bei Date datum = boxDatumM.getSelectedItem(); "Type mismatch: cannot convert from Object to Date". Das liegt wahrscheinlich daran dass ich das Datum beim speichern des Fragebogens als Typ Object speicher und nicht als Date. Das schau ich mir nochmal an...


----------



## Harry Kane (17. Feb 2017)

didi577 hat gesagt.:


> du wirst es mir wahrcheinlich nicht galauben, aber das "value instanceof Date" habe ich registriert und natürlich mit meinem Problem in Verbindung gebracht. Ich habe auch in meiner MySQL Klasse an entsprechender Stelle Lösungen probiert. Ich habe das nur nicht geschrieben.


*seufz* Ok, dann werde ich bei deiner nächsten Frage einfach etwas länger warten, bevor ich mir am Ende unnütz den Kopf zerbreche.
Witzigerweise erkennt man an deinem reply überhaupt nicht, ob das Problem jetzt gelöst ist oder nicht.


didi577 hat gesagt.:


> allerdings meckert er noch bei Date datum = boxDatumM.getSelectedItem(); "Type mismatch: cannot convert from Object to Date". Das liegt wahrscheinlich daran dass ich das Datum beim speichern des Fragebogens als Typ Object speicher und nicht als Date.


Nein, liegt es nicht. Deine Gedankengänge sind manchmal schon interessant. Warum sollte die vom Compiler erlaubte Deklaration eines Methoden-Rückgabewerts in Codeblock A davon abhängen, wie der Rückgabewert der identischen Methode in einem ganz anderen Codeblock B abgespeichert wird?
Die Fehlermeldung kommt ganz einfach daher, weil der Rückgabewert von JComboBox.getSelectedIem aufgrund der Abwärtskompatibilität als Object deklariert ist. Lösung: nach Date casten.

```
Date datum = (Date)boxDatumM.getSelectedItem();
```


----------



## didi577 (17. Feb 2017)

Harry Kane hat gesagt.:


> Ok, dann werde ich bei deiner nächsten Frage einfach etwas länger warten, bevor ich mir am Ende unnütz den Kopf zerbreche


ja, meine Finger sind manchmal zu schnell ;-)
nachdem ich 


Harry Kane hat gesagt.:


> Date datum = (Date)boxDatumM.getSelectedItem();


implementiert habe, kommt jetzt ein Fehler in der Zeile:
pst.setDate(4, datum);
The method setDate(int, java.sql.Date) in the type PreparedStatement is not applicable for the arguments (int, java.util.Date)
bin dem Lösungsvorschlag gefolgt und habe jetzt:
       pst.setDate(4, (java.sql.Date) datum);
die Fehler sind weg aber es kommt bei Ausführung eine Exception:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
er meint die Zeile:
Date datum = (Date)boxDatumM.getSelectedItem();
wenn ich Date als java.sql.date wandle kommt die selbe Exception nur dass er sql statt util nennt

ich kann ja nochmal überlegen ... falls ich in den nächsten Stunden keinen Erfolg melde ...hm... naja


----------



## Harry Kane (17. Feb 2017)

didi577 hat gesagt.:


> ja, meine Finger sind manchmal zu schnell


Du nennst es also ein Kennzeichen von "schnellen Fingern", unvollständige follow ups zu schreiben? Für mich ist das eher ein Kennzeichen vom Gegenteil.
Wenn boxDatumM Strings enthält, kann der DateCellRenderer nicht funktionieren. Als follow-up zu


Harry Kane hat gesagt.:


> Witzigerweise erkennt man an deinem reply überhaupt nicht, ob das Problem jetzt gelöst ist oder nicht.


kann man wohl sagen, dass das Problem nicht gelöst ist.
Nochmal: hole die Datumsangaben als Date aus der Datenbank, und schreibe sie als Date wieder zurück. ResultSet.getDate(int) liefert eine Instanz von java.sql.Date. Da java.sql.Date eine Erweiterung von java.util.Date ist, können Instanzen von java.sql.Date mit dem DateCellRenderer formatiert werden.
Beim Schreiben in die db müssen die Dates Instanzen von java.sql.Date sein, java.util.Date funktioniert nicht. Wenn du schon eine Instanz java.sql.Date hast, kannst du sie direkt abspeichern, ansonsten kannst du aus der Instanz von java.util.Date einfach eine Instanz von java.sql.Date erzeugen.


----------



## didi577 (17. Feb 2017)

Harry Kane hat gesagt.:


> Wenn boxDatumM Strings enthält, kann der DateCellRenderer nicht funktionieren


ich hatte mich die ganze Zeit nur auf die Methode zur Auswertung konzentriert. habe jetzt in der Methode zum laden der Box getString durch "boxDatumM.addElement(rs.getDate(1));" erstetzt. Da war der Haken. Der cellRenderer funktioniert jetzt , ich habe in der oben gezeigten Methode ladenAuswertung noch die Zeile "datum = rs1.getDate(4);" entfernt . Das Problem ist gelöst

Jetzt versende ich ja noch eine Mail mit dem Auswertungsergebnis. Hier wird das Datum noch im Format yyyy-MM-dd angezeigt. Das leuchtet mir ein da wir ja nur die Ansicht in der Auskunft geändert haben. Das Datum füge ich mit dem Befehl 

```
text.append(boxDatum.getSelectedItem());
```
 dem StringBuffer hinzu. Wahrscheinlich wirkt der CellRenderer nicht weil ich hier wieder einen String habe. Habe jetzt

```
Date datum = (Date)boxDatum.getSelectedItem();text.append(datum);
```
 in die Mail Methode geschrieben. Es gibt keinen Fehler aber der CellRenderer wirkt nicht. Kannst du mir sagen warum der Renderer nicht wirkt?


----------



## Flown (17. Feb 2017)

An alle Helfenden hier: Hut ab vor eurer Geduld.

@didi577 Wenn eine Kuh im Stall steht, warum gibt mir der Wasserhahn im Keller keine Milch?

Der CellRenderer ist für die Darstellung in der ComboBox gedacht und dient nur zur Representation des Modells in der UI-Komponente. Das heißt, wenn du deinem Datum eine gewisse Stringformatierung geben möchtest, dann nimm eben einen SimpleDateFormatter und füge es deinem Text mit: `text.append(formatter.format(datum));` hinzu.

Nun mal im Ernst: Warum versuchst du nicht mal einen Schritt zurückzugehen und einmal einen Gesamtblick auf deinen Code zu werfen. Ich glaube du verstehst einfach Abläufe in deinem eigenen Programm nicht (mehr?!). In deinen Posts wird dir alles zäh vorgekaut und es wirkt, als ob es bei dir keine "aha-Momente" gibt. So funktioniert das leider nicht.


----------



## didi577 (17. Feb 2017)

Ja ich danke auch meinen fleißigen Helfern!!!
Ich kenne meine Probleme. Ich habe in meinem Programm jetzt vollständige Funktionalität (ja und es läuft stabil). Ich bin auch froh dass es jetzt durch ist und ich alles in Ruhe nachvollziehen kann. Hab bis hierhin viel gelernt. aha Momente hatte ich genug. Es waren eben nur zu viele Baustellen und zu viel Neuland. 
Grüße


----------

