Eigenartige Datumsberechnung über GregorianCalendar

kodela

Bekanntes Mitglied
Hallo,

für eine App, die an besondere Ereignisse erinnern soll, habe ich die Differenz zwischen dem aktuellen Tag und dem Tag des auszuwertenden Ereignisses über folgende Funktion berechnet:

Java:
    private int getDiff2heute(int jr, int mn, int tg) {

        GregorianCalendar jubeltag = new GregorianCalendar (jr, mn, tg);
        GregorianCalendar is_heute = new GregorianCalendar (jahr, monat, tag);

        long jt = jubeltag.getTimeInMillis();
        long ht = is_heute.getTimeInMillis();

        return (int) ((jt - ht) / 1000 / 60 / 60 / 24);
    }
Mit jr, mn, und tg werden das Jahr, der Monat und der Tag des auszuwertenden Ereignisses übergeben. Auf das aktuelle Datum wird über die global definierten Variablen Jahr, monat und tag zurückgegriffen.

getTimeInMillis() soll für die jeweiligen Tage die Zeit in Millisekunden zurück liefern. Aus der Differenz der beiden Werte wird über den Ausdruck (int) ((jt - ht) / 1000 / 60 / 60 / 24) die Differenz in Tagen berechnet und der aufrufenden Funktion übergeben. Das hat bisher immer funktioniert.

Nun habe ich einen Fall, der möglicherweise mit dem Schaltjahr (2016) zusammenhängt, in dem das Ergebnis falsch ist. Für ein Beispiel habe ich als aktuellen Tag den 02.02.2016 eingestellt. Auszuwerten waren ein Ereignis am 12.02.2016 (Differenz 10 Tage) und eines am 02.03.2016 (Differenz 30 Tage).

Ich denke, dass ich mich nicht verrechnet habe, denn sowohl CALC wie auch Excel kommen zum selben Ergebnis. Hier ein Bild von CALC:

differenz_calc-png.8591

und hier nun ein Bild von dem Ergebnis, zu dem die Funktion getDiff2heute() kommt.

differenz_n-png.8593


Die Differenz für Konrad ist richtig, die für Demetrio dagegen falsch.

Setze ich den aktuellen Tag zum Beispiel auf den 01.03.2016 ist das Ergebnis dagegen auch für Demetrio wieder richtig.

Wer hat dafür eine Erklärung und wer weiß, ob dieser Fehler eventuell verhindert werden kann?

MfG, kodela
 

Anhänge

  • differenz_CALC.png
    differenz_CALC.png
    2,2 KB · Aufrufe: 82
  • differenz_n.png
    differenz_n.png
    23,4 KB · Aufrufe: 81
Zuletzt bearbeitet:

Thallius

Top Contributor
Ka ob es damit zusammen hängt aber Dein Ergebnis wird so oder so falsch sein, wenn zwischen den Daten die Umstellung von Sommer- auf Winterzeit, bzw anders herum liegt.

Tatsächlich scheint es in Java da nicht viel zu geben. Das einzige was ich auf die schnelle gefunden habe ist wohl JodaTime zu benutzen.

Gruß

Claus
 

kodela

Bekanntes Mitglied
Hallo Claus,

da die Umstellung auf die Sommerzeit erst am 27.03. stattfindet, kann ich mir nur schwer vorstellen, dass diese ursächlich für die falsche Rückgabe des Wertes für den 02.03. sein soll. Außerdem wird mit der Sommerzeit ja nur eine Stunde und kein ganzer Tag umgestellt.
Danke für Deinen Hinweis auf JodaTime. Damit muss ich mich aber erst noch näher befassen.

MfG, kodela
 

X5-599

Top Contributor
Also ich bei meinen Versuchen bin ich auf folgende Ursache gekommen. Das Monatsfeld im GregorianCalendar ist 0-basiert. Also musst du, wenn du die Methode aufrufst "immer 1 abziehen".
Code:
getDiff2heute(2016, 1, 2); //2016.02.02
getDiff2heute(2016, 2, 2); //2016.03.02

Und natürlich bei (ich nehme an deiner Instanzvariablen): "monat", ebenfalls.
 

VfL_Freak

Top Contributor
Moin,

ich würde Dir auf Fall nur noch JodaTime empfehlen! Date oder GregorianCalendar haben immer mal wieder so ihre Probleme!
JodaTime erkennt sogar, wenn ein DateTime innerhalb der Lücke beim Wechsel von Winter- auf Sommerzeit erstellt wird!

Zu deinem Problem: wenn es am 1.3. läuft scheint da IMHO irgendein Problem mit dem Schalttag vorzuliegen ...

Gruß Klaus
 

kodela

Bekanntes Mitglied
Also musst du, wenn du die Methode aufrufst "immer 1 abziehen".
Hallo X5-599,

das kann nicht sein. Nimm nur das Beispiel. Da wird die Differenz im ersten Fall ja richtig berechnet und in den vielen anderen Fällen ja auch. Einzig dann, wenn zwischen den beiden Zeiten der 29. Februar liegt, kommt es zu dem Fehler.

MfG, kodela
 

X5-599

Top Contributor
@kodela

Dass es bei dem ersten Beispiel funktioniert liegt daran, dass er den Unterschied vom 02.03.2016 und 12.03.2016 berechnet. Denn wie gesagt ist der Kalendar 0 basiert (für Monate). Wenn du also tatsächlich das Monatsfeld des Kalendars als "2" für Februar setzt ist das falsch. 2 == März.
 

kodela

Bekanntes Mitglied
Hallo InfectedBytes,

hast Du schon
Dass es bei dem ersten Beispiel funktioniert liegt daran, dass er den Unterschied vom 02.03.2016 und 12.03.2016 berechnet. Denn wie gesagt ist der Kalendar 0 basiert (für Monate). Wenn du also tatsächlich das Monatsfeld des Kalendars als "2" für Februar setzt ist das falsch. 2 == März
Hallo X5-599,

da will ich Dir jetzt nicht widersprechen. Ich werde das auf jeden Fall noch prüfen.

Ich habe jetzt aber Dank des Hinweises von InfectedByts über die neue java-time Api eine eindeutig bessere Lösung. Damit sieht die eingangs gezeigte Funktion so aus:
Java:
private static int getDiff2heute(int jr, int mn, int tg) {
  LocalDate today = LocalDate.now();
  LocalDate jubeltag = LocalDate.of(jr, mn, tg);
  long dif = java.time.temporal.ChronoUnit.DAYS.between(today, jubeltag);

  return (int) dif;
}
Allen die mir geholfen haben, vielen Dank.

MfG, kodela
 

kodela

Bekanntes Mitglied
Hallo X5-599,

ja, es ist so, wie Du geschrieben hast. Wenn man die Zählung der Monte bei Null beginnt, dann ist das Ergebnis mit der zuerst von mir gezeigten Version ebenfalls richtig. Wie kann man aber nur einen solchen Fallstrick einbauen, für die Tage und Jahre beginnt die Zählung bei Eins und für die Monate bei Null.

Nochmals danke für Deinen Hinweis.

Mfg, kodela
 

X5-599

Top Contributor
Kann ich dir nicht beantworten. Ist halt schon immer so gewesen... Irgendeinen Grund wird's wohl gehabt haben. Ich bin mir aber sicher, dass schon eine ganze Menge Leute dieses Problem gehabt haben (mich eingeschlossen). Und die neue API LocalDate.of() gibt die Monate von 1 - 12 vor. Sieht also so aus als wenn sie aus ihren Fehlern gelernt hätten :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Hilfe bei Datumsberechnung aus Textfeld Allgemeine Java-Themen 10
kodela Datenübergabe über Buttons Allgemeine Java-Themen 8
W Jar-File Start nur über Terminal Allgemeine Java-Themen 13
A ByteArray über Socket Allgemeine Java-Themen 3
berserkerdq2 Text über einen Shape anzeigen (Scenebuilder) Allgemeine Java-Themen 1
I 2D-Grafik Vektor-Grafik über die Zwischenablage nach Adobe Illustrator transferieren Allgemeine Java-Themen 8
TheSkyRider Methode über DataInputStream "auslösen" Allgemeine Java-Themen 6
I OpenPDF erzeugt riesige PDFs, wenn Grafiken über PdfGraphics2D#drawImage gezeichnet werden Allgemeine Java-Themen 1
T Etikettendrucker über TCP-IP Allgemeine Java-Themen 1
Encera Gleichzeitiges Ausführen und verbinden von 2 Java-Klassen über die Eingabeaufforderung und Eclipse Allgemeine Java-Themen 21
B HTTP Allgemeine Fragen über Suchmaschine nutzen mit Java Allgemeine Java-Themen 20
torresbig Klasse mit extends Calendar über Methoden ändern (Hirnblockade) Allgemeine Java-Themen 7
B Liste ändern während Iteration über Diese? Allgemeine Java-Themen 16
Master3000 Java Konsole über Buffered Reader Zeilenweise auslesen ? Allgemeine Java-Themen 26
J Daten über serielle Schnittstelle empfangen Allgemeine Java-Themen 4
L Aufwandsabschätzung: Android-App Aufnahmefunktion (foto) und zweiter Ebene über dem Foto (teiltransparent) Allgemeine Java-Themen 6
M Registry Autostart Eintrag mit Java erstellen (über Windows cmd) Allgemeine Java-Themen 7
OSchriever Programm über Linux-Kommandozeile ausführen Allgemeine Java-Themen 20
J Namen von Methoden über Reguläre Ausdrücke bearbeiten Allgemeine Java-Themen 6
M Schnelleres Speichern von XML-Daten über URLConnection Allgemeine Java-Themen 4
M Keine weitere Eingabe in der Main möglich. Eventueller Ansatz über while. Allgemeine Java-Themen 8
Drachenbauer Wie kann eine vorgegebene Farbe über einen String erkannt werden? Allgemeine Java-Themen 11
W Variablenübergabe über mehrere Klassen Allgemeine Java-Themen 4
N Über einen Button in JavaFX ein Event über eine Pipeline schicken(Netty) Allgemeine Java-Themen 1
M Threads über Kommandozeile Allgemeine Java-Themen 5
david19 Software AE über Domain laufen lassen Allgemeine Java-Themen 0
Q Selbständig ActionEvent auslösen zum Daten senden über serielle Schnittstelle Allgemeine Java-Themen 7
T Problem mit externen Datenbankzugriff über SSH Tunnel Allgemeine Java-Themen 4
K Auf Dateiverzeichnis extern zugreifen (evtl über XML??) Allgemeine Java-Themen 22
C VisualVM oder Jconsole über Jolokia-Proxy Allgemeine Java-Themen 0
G USB-Pins über Java ansteuern Allgemeine Java-Themen 8
Ernesto95 Best Practice Localization über ResourceBundle Allgemeine Java-Themen 6
C Classpath Neue Klasse über einen Button ausführen Allgemeine Java-Themen 3
C Auslesen auslösen über Button-Click Allgemeine Java-Themen 8
M Fragen beantworten über Textfeldeingabe Allgemeine Java-Themen 5
AssELAss Best Practice Checksumme über jede Spalte zweier Tabellen und vergleichen Allgemeine Java-Themen 3
T Strings über Bluetooth zwischen PC,µc oder Samrtphone senden und empfangen Allgemeine Java-Themen 0
F Try/catch über ganze Klasse Allgemeine Java-Themen 9
HarleyDavidson Best Practice Integer-Zahlenfolge über mehrere Programmstarts Allgemeine Java-Themen 7
T .jar über cmd ausführen (später dann batch) Allgemeine Java-Themen 6
F In OSX: Java-Programm über URI-Scheme aufrufen mit Parameter? Allgemeine Java-Themen 0
C Input/Output Zip Files über Socket senden und empfangen Allgemeine Java-Themen 6
M WebService - Zugriff auf Webservice Methode über Browser Allgemeine Java-Themen 1
C .jar File lässt sich nur über Konsole öffnen Allgemeine Java-Themen 1
L Videodateien über Java öffnen unabhängig vom Format Allgemeine Java-Themen 4
Thallius Hash über serialisiertes Objekt? Allgemeine Java-Themen 3
A Threads Lock über mehrere Abschnitte in verschiedenen Methoden Allgemeine Java-Themen 5
T Daten über port abfangen mit proxy server Allgemeine Java-Themen 12
M Eingabe von Arrays geht über gewünschte Anzahl hinaus Allgemeine Java-Themen 2
L Prüfen, ob Programm über 32bit oder 64bit Java ausgeführt wird Allgemeine Java-Themen 4
F Content-Disposition ermitteln über URL Allgemeine Java-Themen 2
ARadauer Checksumme über BigDecimal Werte Allgemeine Java-Themen 11
A Class Datei aus Verzeichnis über URLClassLoader laden Allgemeine Java-Themen 2
G Darstellung von Ergebnissen einer Dokumentensuche über eine JTable Allgemeine Java-Themen 19
S VLC + Lied über Java starten Allgemeine Java-Themen 17
M HTML-Code von Webseite über Browser oder Console auslesen?? Allgemeine Java-Themen 5
A Sinuston ausgeben und über Mikro Amplitude messen – machbar? Allgemeine Java-Themen 6
R Java-Progamm über Icon starten unter Windows Allgemeine Java-Themen 9
C Daten über URL an PHP verschicken Allgemeine Java-Themen 4
O Fragen über Fragen - Bei Änderung XML-Datei -> Anpassung GUI Allgemeine Java-Themen 7
aze Jar ausführen über Runtime.execute funktioniert nicht Allgemeine Java-Themen 4
S NoSuchMethodError beim Ausführen einer C Methode über JNI Allgemeine Java-Themen 5
H OOP Daten über TCP Allgemeine Java-Themen 5
Pastafari Iterator über nested HashMaps Allgemeine Java-Themen 7
R ListIterator über mehrere Arrays Allgemeine Java-Themen 13
G Interface Laden der Konfiguration über Interfaces sinnvoll? Allgemeine Java-Themen 28
D Player Objekt - Frame über Server anzeigen lassen. Allgemeine Java-Themen 3
B VoIP-Gespräche über Computer führen Allgemeine Java-Themen 3
S Jar-File startet nicht über doppelklick Allgemeine Java-Themen 2
C Java Programm über SSH starten Allgemeine Java-Themen 16
K Internetverbindung über PuTTy herstellen?! Allgemeine Java-Themen 9
C Kapselung Warum graift man auf Variablen nur über Methoden und nich direkt zu? Allgemeine Java-Themen 10
G Auf Kommandozeile über Processobjekt mit Outputstream Allgemeine Java-Themen 3
S Input/Output Binärdatei über Bytestreams Allgemeine Java-Themen 4
S Kommunikation von Core und GUI über Schnittstellen Allgemeine Java-Themen 2
J Explorer über Code starten Allgemeine Java-Themen 15
kodela Problem mit Kopieren über FileChannel Allgemeine Java-Themen 4
L Java und Javascript um Distanz über Google Maps zu berchnen Allgemeine Java-Themen 10
B UNIX Shell befehl über JavaCode ausführen Allgemeine Java-Themen 19
D Java Excel API - Schreiben in Excel lässt sich nicht über Makro starten Allgemeine Java-Themen 18
M Ampelsteuerung über Timer in Java realisieren Allgemeine Java-Themen 3
L CMD über Java öffnen Allgemeine Java-Themen 8
U Mailclient über getDesktop.mail vorbereiten, Problem beim Anhang: Allgemeine Java-Themen 3
R Klasse über Button Event in anderer Klasse informieren Allgemeine Java-Themen 11
R Frequenzausgabe (2 Kanal) über Lautsprecherausgang Allgemeine Java-Themen 22
J Java-Klasse über Konsole starten Allgemeine Java-Themen 6
E FF Einstellungen über Programm ändern? Allgemeine Java-Themen 7
D JVM kann nicht über die jvm.dll gestartet werden? Allgemeine Java-Themen 1
S File im windowexploer öffnen über java Allgemeine Java-Themen 6
J Receive eines Hex-Bytes über COM-Port Allgemeine Java-Themen 4
Nicer Prozess über Prozessnamen beenden Allgemeine Java-Themen 15
reibi File über FileChannel locken Allgemeine Java-Themen 5
B Serialisierung mit Unterobjekten über Netzwerk Allgemeine Java-Themen 3
K Objekt-Austausch zwischen zwei Programmen über System-Clipboard Allgemeine Java-Themen 5
B parallele / Multithreaded Iteration über Map Allgemeine Java-Themen 12
D Unix/Linux Benutzer-Authentifikation über Java Allgemeine Java-Themen 3
M Tastatur eingabe über Buttons Allgemeine Java-Themen 15
S GPS-Maus über USB ansprechen Allgemeine Java-Themen 8
reibi Files über Classpath laden Allgemeine Java-Themen 22
M Selbst geschriebener InputStreamReader über einen beliebigen InputStream Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben