Zeiträume unterteilen, JodaTime

Spewer

Aktives Mitglied
Hallo liebe Leute,

ich bin auf ein Problem gestoßen bei der Programmierung von einem kleinen Programm.
Hoffe, dass Ihr vllt ein paar Tipps für mich habt.

Das Problem ist, dass ich nicht weiß, wie ich einen Zeitraum in mehrere Zeiträume unterteile.
Ziel ist es einen Zeitraum, in Wochen zu unterteilen. (Bsp.: Zeitraum: 1.6 - 31.8, müssten 13 Wochen sein).
Aber hier erst mein Vorgehen. Für sämtliche zeitlichen Berechnungen wollte ich eig. JodaTime benutzen. Bin aber für andere Vorschläge offen.

1) 2 "DateTime"s bestimmen (firstLogin, lastLogout)
2) mit Hilfe von Duration den Zeitraum ermitteln
3) Ermittlung der Anzahl der Tage in diesem Zeitraum
4) Tage dividiert durch 7 = Anzahl der Wochen

Soweit so gut, leider weiß ich jetzt nicht weiter. Wie kann ich einzelne Zeiträume erzeugen, die jeweils eine Woche lang sind. Wahrscheinlich muss man das ganze ja in Arrays speichern.

Java:
int sessionsLength = 0;
	int days = 0;
	long tmpDays = 0;

	users = data.getUsers();
	sessions = data.getSessions();

	sessionsLength = sessions.size();
	DateTime firstLogin = sessions.get(sessionsLength - 1).getLogin();
	DateTime lastLogout = sessions.get(0).getLogout();

	Duration d = new Duration(firstLogin, lastLogout);
	tmpDays = d.getStandardDays();

	days = (int) tmpDays;
	
	totalWeeks = days / 7;

Ein kleiner Ausschnitt aus dem gesamten Projekt, der die Schritte 1-4 zeigt.

Für Tipps und Tricks wäre ich sehr verbunden.

Grüße
Spewer
 

Spewer

Aktives Mitglied
Ich wusste bis dato garnicht, dass es soetwas gibt.
Wie verwendet man denn "totalWeeks" richtig bei einer Duration ?
"getWeeks" bei einer Period hat leider nicht das gewünschte Ergebnis gebracht.
 

faetzminator

Gesperrter Benutzer
Ich verstehe deine Frage nicht. [c]getStandardDays()[/c] liefert gem. API:
Gets the length of this duration in days assuming that there are the standard number of milliseconds in a day.
Nicht berücksichtigt sind da lediglich Schaltsekunden o.ä., das ist allerdings vernachlässigbar. Sicher dass in den beiden [c]DateTime[/c] korrekte Daten drin sind?
 

Spewer

Aktives Mitglied
Der ganze Teil mit "getStandardDays" funktioniert ja soweit auch. Ich bekomme ja die Anzahl der Wochen raus mit dem Code von oben.

Nur wie ich weiter mache weiß ich nicht.
Sinnvollerweise erzeuge ich ein Array, wo ich die Daten der einzelnen Wochen reinspeicher.
Nur bei der praktischen Umsetzung scheitere ich :(
 

jgh

Top Contributor
also hier mal eine schnell Möglichkeit das mit den StandardKlassen des SDK´s zu lösen.

Java:
	public static void main(String[] args) {

		Calendar c1 = new GregorianCalendar();
		Calendar c2 = new GregorianCalendar();
		c1.set(Calendar.MONTH, 5);// zu beachten, dass die Monatszahl mit 0
									// beginnt für Janunar bspw
		c1.set(Calendar.DAY_OF_MONTH, 1);
		c2.set(Calendar.MONTH, 7);
		c2.set(Calendar.DAY_OF_MONTH, 31);
		setCalendarToBeginOfDays(c1);
		setCalendarToBeginOfDays(c2);
		long diff = c2.getTimeInMillis() - c1.getTimeInMillis();

		int days = (int) (diff / 1000l / 60l / 60l / 24l);
		int week = (int) (diff / 1000l / 60l / 60l / 24l / 7);

		Date[] dateArray = new Date[week * 2];
		for (int i = 0; i < dateArray.length; i++) {
			dateArray[i] = c1.getTime();
			c1.add(Calendar.DAY_OF_YEAR, 7);
			i++;
			dateArray[i] = c1.getTime();
		}
		for (int i = 0; i < dateArray.length; i = i + 2) {
			System.out.println(dateArray[i] + " - " + dateArray[i + 1]);

		}
		System.out.println("Days=" + days + " weeks=" + week);

	}

	public static void setCalendarToBeginOfDays(Calendar c) {
		c.set(Calendar.MILLISECOND, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.HOUR_OF_DAY, 0);
	}
 

jgh

Top Contributor
es gibt ja einige/viele hier, die auf JODA schwören...gibt sicherlich einige Bereiche, wo Joda bequemer und einfacher zu gebrauchen ist...aber grundsätzlich kann man imho das alles auch (manchmal zugegebenermaßen umständlich) mit den Standardklassen erreichen.
 

Spewer

Aktives Mitglied
Gibt es die Möglichkeit mit der Standardklasse eine Abfrage zu machen so wie:
Java:
is between
?

Also
Java:
if (Date A.is between(dateArray[i]))
 

faetzminator

Gesperrter Benutzer
Davon ausgegangen, dass die jeweilige Datumsklasse [c]Comparable[/c] ist kannst du das relativ elegant lösen:
Java:
if (someDate.compareTo(date1) > 0 && someDate.compareTo(date2) < 0) { ... }
 

Spewer

Aktives Mitglied
Hab doch noch eine Frage.
Wenn man das so coded :
Java:
 for (int i = 0; i < dateArray.length; i++) {
            dateArray[i] = c1.getTime();
            c1.add(Calendar.DAY_OF_YEAR, 7);
            i++;
            dateArray[i] = c1.getTime();
        }

dann erzeugt man ja ein eindimensionales Array mit folgendem Inhalt:
datum 1
datum 2
datum 3
.
.
.

Wäre es auch möglich ein Array der Form:
Code:
dateArray[week][]
zu erzeugen, was dann so gefüllt wird:
datum 1 - datum 2
datum 2 - datum 3
datum 3 - datum 4
.
.
.

Stehe da gerade irgendwie auf dem Schlauch.
 

jgh

Top Contributor
klar kannst du das ....entweder ein 2 -dim Date Array, oder du baust dir eine Klasse bspw. MyWeek...die rudimentär so oder ähnlich aussieht...

Java:
Date[][] dateArray = new Date[week][2];
		MyWeek[] myWeekArray = new MyWeek[dateArray.length];

	class MyWeek {
		Date startWeek;
		Date endWeek;
	}
 

Spewer

Aktives Mitglied
Jetzt hat sich leider ein weiteres Problem ergeben...
Ich möchte nun keine Einteilung mehr in Wochen sondern in Monaten.

Das heißt, bei einem Zeitraum vom zb.: 15.1 - 29.3 soll das DateArray so aussehen: [15.01 , 01.02 , 01.03]

Mir ist nur nicht wirklich klar, wie ich das mit den Standardklassen machen kann.

Ich kann eventuell mit
Code:
calender1.get(Calendar.DAY_OF_MONTH);
den Tag bestimmen aber leider weiß ich nicht wirklich weiter.
Eine Schleife, die immer einen Tag addiert und sobald
Code:
calender1.get(Calendar.DAY_OF_MONTH); = 1
ist, im Array einen Eintrag mehr ?

Oder gibt es wohl eine einfache, bessere Art und Weise.
Hoffe, dass das überhaupt verständlich ist :oops:

Edit: Habe es jetzt so gelöst, jedenfalls glaube ich, dass es so richtig funktioniert.
Java:
int dif = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
	
	dateArray = new Date[dif * 2];
	for (int i = 0; i < dateArray.length; i++)
	{
	    dateArray[i] = c1.getTime();
	    c1.roll(Calendar.MONTH, 1);
	    i++;
	    dateArray[i] = c1.getTime();
	}

Edit Edit : Die Lösung oben funktioniert leider nur wenn das erste Datum zb. der 01.06 ist. wenns der 03.06 ist, geht die logik nicht mehr auf
 
Zuletzt bearbeitet:

jgh

Top Contributor
ungetestet, Bedingung ist das c1 das ältere Datum gegenüber c2 hält...und wirklich schön ist es auch nicht...mal sehen, evtl. heute abend etwas sinnvolleres...


Java:
Calendar c1 = new GregorianCalendar();
		Calendar c2 = new GregorianCalendar();
		c1.set(Calendar.MONTH, 1);
		c1.set(Calendar.DAY_OF_MONTH, 15);
		c2.set(Calendar.MONTH, 9);
		c2.set(Calendar.DAY_OF_MONTH, 14);

		int monatsArrayGroesse = (c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR))
				* 12 + (c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH) + 1);

		Date[] dateArray = new Date[monatsArrayGroesse];
		dateArray[0] = c1.getTime();
		for (int i = 1; i < dateArray.length; i++) {
			while (c1.get(Calendar.DAY_OF_MONTH) != 1) {
				c1.add(Calendar.DAY_OF_MONTH, 1);
			}
			dateArray[i] = c1.getTime();
			c1.add(Calendar.MONTH, 1);

		}
		System.out.println(Arrays.toString(dateArray));
 

Spewer

Aktives Mitglied
Java:
c1.setTime(firstLogin);
	c2.setTime(lastLogout);

	month = (c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR)) * 12
		+ (c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH) + 1);

	dateArray = new Date[month];

	if (c1.get(Calendar.DAY_OF_MONTH) != 1)
	{
	    dateArray[0] = c1.getTime();

	    for (int i = 1; i < dateArray.length; i++)
	    {
		while (c1.get(Calendar.DAY_OF_MONTH) != 1)
		{
		    c1.add(Calendar.DAY_OF_MONTH, 1);
		}
		dateArray[i] = c1.getTime();
		c1.add(Calendar.MONTH, 1);
	    }
	}
	else
	{
	    for (int i = 0; i < dateArray.length; i++)
	    {
		while (c1.get(Calendar.DAY_OF_MONTH) != 1)
		{
		    c1.add(Calendar.DAY_OF_MONTH, 1);
		}
		dateArray[i] = c1.getTime();
		c1.add(Calendar.MONTH, 1);
	    }
	}

Schaut jetzt im Projekt so aus.
Eigentlich habe ich nur den
Code:
if - else
Part reingebaut, damit sichergestellt wird, dass er nicht zweimal das selbe Datum ins Array schreibt, wenn der Zeitraum am 1. des Monats anfängt.
 

Spewer

Aktives Mitglied
Nach den ganzen Berechnungen von oben, stehe ich nun vor dem Problem nicht einfach auszuwählen ob Zeitraum = Wochen oder Monate, sondern nun will ich es umsetzen, dass ich ein beliebiges Intervall eingebe.
Beispiel:
Zeitraum: 1.6 - 1.9
Intervall = 2

Zuerst habe ich mir überlegt, sollte ich die Differenz der beiden Daten ausrechnen
Java:
long diff = c2.getTimeInMillis() - c1.getTimeInMillis();
Danach sollte die Differenz durch die Anzahl an Intervallen dividiert werden. Das Ergebnis ist ja dann die Zeit (in Millis) von einem Interval
Java:
long oneInterval= diff / intervals;

Nun erstelle ich wieder mein DateArray mit der Länge von den Intervallen
Java:
dateArray = new Date[intervals];

nur weiß ich leider nicht weiter... habe einiges versucht nur das Problem ist, dass wenn Intervall = ausgewählt wird, sollen im Array 3 Werte stehen [1.6; 15.7; 1.9]. Habe folgendes ausprobiert aber das geht nicht wirklich.
Java:
if (oneInterval <= Integer.MAX_VALUE)
	{
	    dateArray = new Date[intervals + 1];

	    for (int i = 0; i < dateArray.length; i++)
	    {
		dateArray[i] = c1.getTime();
		c1.add(Calendar.MILLISECOND, (int) oneInterval);
	    }
	}
	else
	{
	    int oneIntervalMinutes = (int) (diff / 1000l / 60l);

	    dateArray = new Date[intervals + 1];

	    for (int i = 0; i < dateArray.length; i++)
	    {
		dateArray[i] = c1.getTime();
		c1.add(Calendar.MINUTE, oneIntervalMinutes);
	    }
	}

Hat da nochmal jemand einen Tipp für mich ?
 

jgh

Top Contributor
das ist nicht logisch...wo soll denn bei 2 Intervallen im o.g. Zeitraum die Logik herkommen, dass der 15.7 die Intervalle unterteilen soll?
immer inc. der genannten Tage:
1.6. -30.6 = 30 Tage
1.7 - 31.7 = 31 Tage
1.8 - 30.8 = 30 Tage
+1.9 = 1 Tag
Summe = 92 Tage / 2 Intervalle = 46 Tage/intervall => 1.6 + 30 Tage = 1.07

1.7+16 Tage = 17.07 als Intervallgrenze
 
Zuletzt bearbeitet:

Spewer

Aktives Mitglied
Hehe, ja das ist mir auch 10 Min nach meinem Post aufgefallen. Musste die Logik etwas ändern.
Hier der fertige Code soweit, damit klappt es gut:

Java:
long diff = c2.getTimeInMillis() - c1.getTimeInMillis();
	long oneInterval = diff / intervals;
		
	int minutes = (int) (oneInterval / 1000l / 60l );
	
	
	dateArray = new Date[intervals + 1];
	
	dateArray[0] = c1.getTime();
	dateArray[dateArray.length - 1] = c2.getTime();
	
	for (int i = 1; i < dateArray.length - 1; i++)
	{
	    c1.add(Calendar.MINUTE, minutes);
	    dateArray[i] = c1.getTime();
	}
 

Ähnliche Java Themen

Neue Themen


Oben