View Full Version : Datum '01.01.0001' per JDBC in Datenbank schreiben
Hallo,
wir arbeiten mit Datumsfelder ohne null-Behandlung (date not null). Nicht gefüllte Datumsfelder werden mit '01.01.0001' vorbelegt.
Hat jemand eine Idee, wie ich es hinbekomme unter Java mit JDBC Datumsfelder mit Wert '01.01.0001' zu füllen?
Gruß
M. Withake
Ja, aber wo ist das Problem?
Hallo,
wir arbeiten mit Datumsfelder ohne null-Behandlung (date not null). Nicht gefüllte Datumsfelder werden mit '01.01.0001' vorbelegt.
Hat jemand eine Idee, wie ich es hinbekomme unter Java mit JDBC Datumsfelder mit Wert '01.01.0001' zu füllen?
Gruß
M. Withake
Das wird so wohl nicht gehen, da die meisten Date-Formate nur ab dem 1.1.0100 funktionieren.
Dies liegt wohl daran, dass ein Datum intern als Double-Wert in Anzahl Tage seit dem 31.12.1899 gespeichert werden.
2 = 1.1.1900
Werte < 0 liegen eben davor.
Hier kannst du nur mit Direkt-Sql was erreichen, in dem du das Datum im ISO-Format angibst:
insert into myfile (MyDate) values('0001-01-01')
Die weitere Alternative ist, du bestimmst für die Tabelle den Defaultwert '0001-01-01' und läßt beim Insert das Feld einfach aus:
create mytable (mydate as date not null default '0001-01-01')
@Dieter
Irgendwo liegt es an der Interpretation eines Datums.
Ist die Jahreszahl 2-Stellig wird eben selbständig 1900 oder 2000 addiert.
Erst wenn die Jahreszahl mindestens 3-stellig ist (also 100), bleibt sie wie sie ist.
@Baldur: zweistellig gibt es in Java nicht für Jahreszahlen, da gibt es nur int und da wo das bei 1900 aufsetzt, sagt man halt -1899, wenn man das Jahr 1 haben will.
Auch mit dem Monaten hat das Tücken, die gehen hie und da von 0 bis 11, da muss man 0 nehmen, wenn man 1 drinstehen haben will.
Aber all dies ist mit good old RTFM lösbar und Herr Google liefert sogar Beispiele.
Da gibt es noch weitere Möglichkeiten, was man mit Datümern an Irrtümern produzieren kann, von der Dateierstellung, über Systemwerte der AS/400, den Treiber und Treibereinstellungen bis hin zum Java Programm.
Summa Summarum: wer sich ein wenig mehr Mühe beim Fragen gibt, bekommt auch schnell und präzise Antworten.
mfg
Dieter Bender
@Dieter
Irgendwo liegt es an der Interpretation eines Datums.
Ist die Jahreszahl 2-Stellig wird eben selbständig 1900 oder 2000 addiert.
Erst wenn die Jahreszahl mindestens 3-stellig ist (also 100), bleibt sie wie sie ist.
@Dieter Es ging darum den Wert mit der Methode setDate() der Klasse PreparedStatement zu schreiben und ich keine java.sql.Date-Objekt mit dem entsprechende Wert für '01.01.0001' hinbekam.
Habe inzwischen aber eine Lösung gefunden:
GregorianCalendar cal = (GregorianCalendar)GregorianCalendar.getInstance() ;
cal.set(1, 0, 1, 0, 0, 0);
Date emptyDate = new Date(cal.getTimeInMillis());
oder kurz
Date emptyDate = new Date(-62135773199359l)
Wir nutzten den Wert '01.01.0001' als "Leerwert" weil ein RPG-CLEAR auf ein Datumsfeld genau diesen Wert ergibt und wir auf das umständlichen Handling von NULL-Werten in der Datenbank ansonsten gut verzichten können.
Gruß
M. Withake
Die AS/400 akzeptiert ein Datum auch als String im ISO-Format.
Hallo,
das habe ich mir schon gedacht, dass da prepared Statement und Date im Spiel ist; dabei ist halt die Tücke, dass da auf das Jahr 1900 draufgezählt werden - nimmt man da -1899, dann passt es.
Wenn der Treiber das alles richtig macht, und die Datenbank mit not null und default 1.1.0001 definiert ist, dann müsste man eigentlich auch mit prepStm.setDate(n, null) den gewünschten Effekt erreichen.
Ansonste müsste eigentlich auch DateFormat.parse("01.01.0001") zum gewünschten Ziel führen.
mfg
Dieter Bender
@Dieter Es ging darum den Wert mit der Methode setDate() der Klasse PreparedStatement zu schreiben und ich keine java.sql.Date-Objekt mit dem entsprechende Wert für '01.01.0001' hinbekam.
Habe inzwischen aber eine Lösung gefunden:
GregorianCalendar cal = (GregorianCalendar)GregorianCalendar.getInstance() ;
cal.set(1, 0, 1, 0, 0, 0);
Date emptyDate = new Date(cal.getTimeInMillis());
oder kurz
Date emptyDate = new Date(-62135773199359l)
Wir nutzten den Wert '01.01.0001' als "Leerwert" weil ein RPG-CLEAR auf ein Datumsfeld genau diesen Wert ergibt und wir auf das umständlichen Handling von NULL-Werten in der Datenbank ansonsten gut verzichten können.
Gruß
M. Withake
Der Nachteil, wenn man ein Feld für den Insert benennt, zieht der Default der DB nicht !
Nur wenn beim Insert ein Feld nicht benannt wird, wird der Default genommen.
Setzt du das Feld auf NULL, gibts einen Fehler, wenn NULL nicht erlaubt ist.
Wie gesagt, die AS/400 und manche andere DB's erlauben auch Strings als Parameter, wenn das Datum eindeutig erkannt werden kann.
Dies ist bei der AS/400 eben das ISO-Format.
In VB löse ich das eben so:
if ... then
.Parameter(MyDate)="0001-01-01"
else
.Parameter(MyDate)=format(MyDate, "jjjj-mm-dd")
end if
Ich denke, für Java gibts ähnliches.
das mit dem Null war nicht einmal die zweitbeste Idee, das war mir um diese Zeit gerade nicht präsent. Aber Workarounds brauchts da in Java nicht, das Date Objekt kann auch den 1.1.0001 aufnehmen, ist allerdings nicht gerade das Highlight von Java und ein wenig hakelig - wens stört, der kann sich da auch einen kleinen Wrapper für schreiben.
mfg
Dieter Bender
Der Nachteil, wenn man ein Feld für den Insert benennt, zieht der Default der DB nicht !
Nur wenn beim Insert ein Feld nicht benannt wird, wird der Default genommen.
Setzt du das Feld auf NULL, gibts einen Fehler, wenn NULL nicht erlaubt ist.
Wie gesagt, die AS/400 und manche andere DB's erlauben auch Strings als Parameter, wenn das Datum eindeutig erkannt werden kann.
Dies ist bei der AS/400 eben das ISO-Format.
In VB löse ich das eben so:
if ... then
.Parameter(MyDate)="0001-01-01"
else
.Parameter(MyDate)=format(MyDate, "jjjj-mm-dd")
end if
Ich denke, für Java gibts ähnliches.