Nächster möglicher Tag bekommen / Nächste mögliche Zeit bekommen

beta20

Top Contributor
Hallo zusammen,

ich möchte gerne folgendes realisieren:

Ich definiere wann ein Schedule laufen darf.
Hierzu habe ich eine Klasse "Schedule" mit folgenden Attributen.
Aufgeteilt ist das in Tage wann der Schedule laufen darf und in der Zeit wann der Schedule laufen darf.
Bei der Zeit gibt es verschiedene Optionen:
- IMMEDIATELY -> Sofort
- SPECIFIC_TIME, // Spezielle Uhrzeit (wird dann in sendTimeSpecific gespeichert)
- ONLY_BETWEEN, // Nur Zwischen(wird dann in sendTimeFrom / sendTimeUntil gespeichert)

Java:
    ///////////////
    //// DAY //////
    ///////////////
    
    private boolean monday = true;
    private boolean tuesday = true;
    private boolean wednesday = true;
    private boolean thursday = true;
    private boolean friday = true;
    private boolean saturday = true;
    private boolean sunday = true;

    ///////////////
    //// TIME //////
    ///////////////

    // TimeType
    public enum TimeType {
        IMMEDIATELY, // Sofort
        SPECIFIC_TIME, // Spezielle Uhrzeit
        ONLY_BETWEEN, // Nur zwischen Uhrzeit
    }
    private String timeType = CampaignType.EMAIL.toString();

    private Date sendTimeSpecific;
    private Date sendTimeFrom;
    private Date sendTimeUntil;

Was ich nun prüfen möchte, ob eine entsprechende Zeit den eingestellten Kriterien entspricht.

Calendar calendar = Calendar.getInstance();
int currentDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
-> So kann ich ja den Wochentag prüfen.

Nun kann es aber sein, dass der Wochentag richtig ist, aber die Zeit nicht passt (im Vergleich zur jetztigen Zeit). Dann soll die nächstmögliche Option gefunden werden. Hier hängt es gerade an meiner Logik und ich weiß nicht so genau wie ich das realisieren kann.
Bspw:
Schedule soll jeden Montag und Samstag um 11:00 Uhr laufen
Derzeitige Zeit:
Wochentag = Samstag
Uhrzeit = 11:15 Uhr

-> Das heißt der Wochentag passt, aber die Uhrzeit passt nicht. D.h. der Schedule soll frühestens wieder am Montag, 11:00 Uhr laufen.

if (schedule.isSunday() && dayOfWeek == 0) {
// Prüfe Zeit
}
if (schedule.isMonday() && dayOfWeek == 1) {,
// Prüfe Zeit
}

Gerade auch mit der Logik wenn Samstag ist (weekDay == 6) dann wieder bei 0 anzufangen tue ich mir schwer.

Kann mir hier jemand weiterhelfen?
 
X

Xyz1

Gast
Kann mir hier jemand weiterhelfen
Am Einfachsten wohl so, das funktioniert aber nur innerhalb dieses Jahres, zum Jahreswechsel müsste man sich etwas überlegen...
Java:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class S {
	private static HashMap<Integer, ArrayList<Integer>> map = new HashMap<>();

	public static LocalDateTime scheduleBetween(int minutes, int days) {
		LocalDateTime todayMidnight = LocalDateTime.of(LocalDate.now(ZoneId.of("Europe/Berlin")), LocalTime.MIDNIGHT);
		todayMidnight = todayMidnight.plusMinutes(minutes);

		LocalDateTime now = LocalDateTime.now(ZoneId.of("Europe/Berlin")).plusMinutes(1);

		if (!now.isBefore(todayMidnight)) {
			todayMidnight = todayMidnight.plusDays(1);
		}
		while (map.containsKey(todayMidnight.getDayOfYear())) {
			todayMidnight = todayMidnight.plusDays(1);
		}
		map.put(todayMidnight.getDayOfYear(), new ArrayList<>(List.of(minutes)));

		return todayMidnight;
	}

	public static void main(String[] args) {
		for (int i = 0; i < 10; i++) {
			System.out.println( scheduleBetween(i * 60, 0) );
		}
	}
}


Bei Fragen einfach nachfragen bitte...
 
X

Xyz1

Gast
Ups, todayMidnight = todayMidnight.plusDays(days); nach todayMidnight = todayMidnight.plusMinutes(minutes); noch vergessen gehabt (da aber immer der nächstmögliche Tag (+0) gewählt werden soll, wohl nicht schlimm...)
 

beta20

Top Contributor
Danke.

Aber so ganz verstehe ich den Code nicht...
Wo ist denn dein Datum, mit dem du in die Methode reingehst?

Warum die Schleife in der Main Methode?
Warum < 10?

Ich möchte doch mit einem bestimmten Datum in die Methode reingehen und mit einem neuen Datum wieder rausgehen...
 

mrBrown

Super-Moderator
Mitarbeiter
Calendar calendar = Calendar.getInstance();
Ich wiederhole mich möglicherweise, aber nimm die neue Time-API (oder JodaTime wenn < Java 8). Mit Calender machst du alles nur x-Fach kompliziert...


Und generell zu der Frage:

- IMMEDIATELY -> Sofort
- SPECIFIC_TIME, // Spezielle Uhrzeit (wird dann in sendTimeSpecific gespeichert)
- ONLY_BETWEEN, // Nur Zwischen(wird dann in sendTimeFrom / sendTimeUntil gespeichert)
Diese drei geben jeweils nur die Zeit an, und zusätzlich gibt es einen Wochentag?

SPECIFIC_TIME wäre dann sowas wie Montags, 11 Uhr,
ONLY_BETWEEN Montag, 11-13 Uhr
und IMMEDIATELY wäre was?


Und ermittelt werden soll jeweils der nächste gültige Zeitpunkt, und nicht, ob der aktuelle Zeitpunkt geeignet ist?
 
X

Xyz1

Gast
Also habe mir das schon durchgelesen was Du geschrieben hattest.
Der Methode scheduleBetween werden Minuten und Tage übergeben.
Wenn zum Beispiel etwas um 11:15 Uhr um nächstmöglichen Tag laufen soll dann ruft man scheduleBetween(11*60 + 15, 0); auf.
scheduleBetween prüft
- kann der Schedule am selben Tag laufen?
- wann kann der Schedule in den nächsten Tagen laufen?
 

beta20

Top Contributor
Ich wiederhole mich möglicherweise, aber nimm die neue Time-API (oder JodaTime wenn < Java 8). Mit Calender machst du alles nur x-Fach kompliziert...


Und generell zu der Frage:


Diese drei geben jeweils nur die Zeit an, und zusätzlich gibt es einen Wochentag?

SPECIFIC_TIME wäre dann sowas wie Montags, 11 Uhr,
ONLY_BETWEEN Montag, 11-13 Uhr
und IMMEDIATELY wäre was?


Und ermittelt werden soll jeweils der nächste gültige Zeitpunkt, und nicht, ob der aktuelle Zeitpunkt geeignet ist?
Ist leider nun so historisch gewachsen, dass ich "Date" nehme und nicht JodaTime etc. Auch aus dem Hintergrund dass Primefaces noch kein Support hat für Time API...

Ja, sieht dann so aus in der GUI:
12472

Doch, wenn der Zeitpunkt natürlich passt, dann soll dieses Datum ausgegeben werden. Falls nicht, soll eben der nächst mögliche Zeitpunkt ausgegeben werden.

also grob gesagt soll sowas herauskommen:

Java:
Date generateScheduleDate(Date currentPlannedDate){

// Datum passt mit den Einstellungen vom Schedule, dann currentPlannedDate zurückgeben
return currentPlannedDate;

// Datum passt mit Einstellung von Schedule NICHT, dann neu berechnen und nächstmögliches Datum ausgeben
-> Das fehlt bisher...
}
 

Anhänge

  • 1570877142701.png
    1570877142701.png
    18,1 KB · Aufrufe: 37

mrBrown

Super-Moderator
Mitarbeiter
Ist leider nun so historisch gewachsen, dass ich "Date" nehme und nicht JodaTime etc. Auch aus dem Hintergrund dass Primefaces noch kein Support hat für Time API...
Ich erinner mich daran, dazu schon mal was gesagt zu haben. Irgendwas aus {View sollte nicht das Model bestimmen, Converter nutzen, notfalls Fassade um das Model, ...}


Mit der alten API keine Ahnung wie man's umsetzen würde, mit der neuen API:

Java:
LocalDateTime getNext(LocalTime time, DayOfWeek... days) {
    LocalDate today = LocalDate.now();
    
    //prüfen, ob „heute“ einer der gültigen Tage ist
    if (Arrays.asList(days).contains(today.getDayOfWeek())) {
        //wenn ja, prüfen ob die Uhrzeit noch in der Zukunft liegt
        if (today.atTime(time).isAfter(LocalDateTime.now())) {
            //wenn ja, zurückgeben
            return today.atTime(time);
        }
    }

    final Optional<LocalDateTime> min = Arrays.stream(days)
            //jeweils den nächsten Tag für den Wochentag berechnen 
            .map(day -> today.with(next(day)))
            //den Tag auf die gewünschte Uhrzeit setzen
            .map(day -> day.atTime(time))
            //den nächsten (also kleinsten) suchen
            .min(Comparator.naturalOrder());
    
    return min.get();
}

Für ONLY_BETWEEN muss man halt zusätzlich noch im if das Enddatum beachten.
 
Zuletzt bearbeitet:

beta20

Top Contributor
Ok, aber wo gehst du mit den Bedingungen des Schedules herein?
Die Zeit wird gar nicht beachtet?
ONLY_BETWEEN und SPECIFIC_TIME ?
 

mrBrown

Super-Moderator
Mitarbeiter
Das ist nur der Code für SPECIFIC_TIME (deshalb unten die Ergänzung, das man für den anderen Fall mehr machen muss).


Was für Bedingungen fehlen dir? Falls es noch andere als Tag und Uhrzeit gibt, hast du die bisher nicht erwähnt. Falls du die beiden meinst, die werden als Methodenparamter übergeben.

EDIT: hab mal Kommentare im Code ergänzt
 
Zuletzt bearbeitet:
X

Xyz1

Gast
Ist leider nun so historisch gewachsen, dass ich "Date" nehme und nicht JodaTime etc. Auch aus dem Hintergrund dass Primefaces noch kein Support hat für Time API
also grob gesagt soll sowas herauskommen:
Dann wäre es doch einfach nur
Java:
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

public class S {
	private static boolean[] days = new boolean[7];

	public static Date generateScheduleDate(Date currentPlannedDate) {
		int a = LocalDateTime.now(ZoneId.of("Europe/Berlin")).getDayOfWeek().getValue() - 1;
		int b = a;
		int c = 0;
		while (c < 7 && days[b]) {
			b = (b + 1) % 7;
			c++;
		}
		if (!days[b]) {
			days[b] = true;
			return Date.from( currentPlannedDate.toInstant().atZone(ZoneId.of("Europe/Berlin")).toLocalDateTime().plusDays(c).atZone(ZoneId.of("Europe/Berlin")).toInstant() );
		} else {
			return null;
		}
	}

	public static void main(String[] args) {
		for (int i = 0; i < 10; i++) {
			System.out.println( generateScheduleDate(new Date()) );
		}
	}
}


Man bräuchte zumindest ein Array ....
 
X

Xyz1

Gast
Obwohl, das ist alles nicht stimmig
Ich würde die komplette Woche in Minuten einteilen. Pro Tag ist dann eben nur ein Schedule erlaubt.
Wär das möglich?
 

beta20

Top Contributor
Dann wäre es doch einfach nur
Java:
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

public class S {
    private static boolean[] days = new boolean[7];

    public static Date generateScheduleDate(Date currentPlannedDate) {
        int a = LocalDateTime.now(ZoneId.of("Europe/Berlin")).getDayOfWeek().getValue() - 1;
        int b = a;
        int c = 0;
        while (c < 7 && days[b]) {
            b = (b + 1) % 7;
            c++;
        }
        if (!days[b]) {
            days[b] = true;
            return Date.from( currentPlannedDate.toInstant().atZone(ZoneId.of("Europe/Berlin")).toLocalDateTime().plusDays(c).atZone(ZoneId.of("Europe/Berlin")).toInstant() );
        } else {
            return null;
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            System.out.println( generateScheduleDate(new Date()) );
        }
    }
}


Man bräuchte zumindest ein Array ....

Danke. Ich verstehe jedoch deine Schleife nicht in der Main - Methode. Ebenfalls verstehe ich nicht, was das mit Jahr zu tun haben soll?
Mit Funktionen wie addDate zB bekomme ich doch ohnehin das richtige Jahr?
In der Methode fehlen doch auch noch die Parameter vom Schedule?
 
X

Xyz1

Gast
Ich verstehe jedoch deine Schleife nicht in der Main
Wieso nicht was gibt es daran nicht zu verstehen? Das ist ein Beispiel wie es aufgerufen werden könnte
Ebenfalls verstehe ich nicht, was das mit Jahr zu tun haben soll
Da steht doch nischt mit Jahr...
In der Methode fehlen doch auch noch die Parameter vom Schedule
Diese Methode (den Methodenkopf) hattest Du doch vorgegeben


Nein, der Schedule kann doch vom Benutzer selbst eingestellt werden.... (Siehe Screenshot oben
Der muss doch irgendwie gespeichert werden. Sonst ist es doch einfach nur die Abfrage, ob ein Platz frei ist.
 

beta20

Top Contributor
Wieso nicht was gibt es daran nicht zu verstehen? Das ist ein Beispiel wie es aufgerufen werden könnte
Da steht doch nischt mit Jahr...
Diese Methode (den Methodenkopf) hattest Du doch vorgegeben
Der muss doch irgendwie gespeichert werden. Sonst ist es doch einfach nur die Abfrage, ob ein Platz frei ist.

"Am Einfachsten wohl so, das funktioniert aber nur innerhalb dieses Jahres, zum Jahreswechsel müsste man sich etwas überlegen..."
-> deshalb

- Für was braucht man überhaupt die Schleife?
Ja, das "Schedule" - Objekt fehlt in der Methode um zu prüfen, ob die Bedingung auch wirklich passt. Also Prüfung gegen definierten Wochentag, definierte Zeit....
 

beta20

Top Contributor
Wie kommst du dann darauf, dass es um „freie Plätze“ geht? Hab ich irgendwas völlig missverstanden? o_O
Nein, darum geht es nicht....

1) Habe ein Datum
2) Habe Einstellungen von einem Schedule
3) Prüfen, ob das Datum die Kriterien vom Schedule erfüllt
4.1) Wenn ja, dieses Datum zurückgeben
4.2) Wenn nein, nächstmögliches Datum berechnen anhand der Einstellungen vom Scheduler
 

mrBrown

Super-Moderator
Mitarbeiter
Es geht gar nicht darum, den kleinsten nächstmöglichen Zeitpunkt zu bestimmen, sondern nur eine Abfrage, ob es an einem Tag noch kein Schedule gibt.
Doch, genau um den "kleinsten nächstmöglichen Zeitpunkt" geht es...


Nein, darum geht es nicht....

1) Habe ein Datum
2) Habe Einstellungen von einem Schedule
3) Prüfen, ob das Datum die Kriterien vom Schedule erfüllt
4.1) Wenn ja, dieses Datum zurückgeben
4.2) Wenn nein, nächstmögliches Datum berechnen anhand der Einstellungen vom Scheduler
Dann hab ich dich richtig verstanden.

Wie gesagt: nutz in deinem Model java.time und bau es vernünftig auf (7 booleans z.B. sind nicht vernünftig). Selbst wenn du dass dann nach außen als Date verfügbar machst, musst du es ja da drin nicht so machen.

Eine Möglichkeit dafür steht dann in #9, muss natürlich noch an die einzelnen Fälle angepasst werden, zB die drei Varianten und das "Testdatum" (was da einfach now ist, das sollte natürlich von außen kommen.)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Liste von Integer -> Nächster Wert bekommen Java Basics - Anfänger-Themen 5
A wie durch klicken regeln dass nächster "case" auge Java Basics - Anfänger-Themen 15
J Nächster Buchstabe, aus IBM wird HAL Java Basics - Anfänger-Themen 2
Ibrahim Anzahl möglicher Reiserouten zurückgeben Java Basics - Anfänger-Themen 5
A Threads Reentrantlock | NullpointerException möglicher Deadlock? Java Basics - Anfänger-Themen 0
R Operatoren Möglicher Fehler im Buch Programmieren lernen mit Java Java Basics - Anfänger-Themen 7
I XML einlesen und Objekte bekommen Java Basics - Anfänger-Themen 2
I Dateigröße von einem InputStream oder byte[] bekommen Java Basics - Anfänger-Themen 2
I Lambda map -> Children bekommen Java Basics - Anfänger-Themen 1
O Warum bekommen wir nicht die Referenz vom zurückgegebenen Objekt? Java Basics - Anfänger-Themen 4
G Methoden Informationen aus zwei Objekte bekommen? Java Basics - Anfänger-Themen 6
B Map<String, FilterMeta, wie Wert bekommen? Java Basics - Anfänger-Themen 4
M Java GUI explorer aufrufen um Pfad zu bekommen Java Basics - Anfänger-Themen 3
C Projekte in 2 versch. Arbeitsbereichen: auf ein Projekt verweisen (ohne Fehler zu bekommen) Java Basics - Anfänger-Themen 8
P Speziellen Dateipfad bekommen Java Basics - Anfänger-Themen 6
B Von Array nur eine bestimmte Anzahl bekommen Java Basics - Anfänger-Themen 3
B Name von Verzeichnis bekommen - Files von einem Ordner auslesen Java Basics - Anfänger-Themen 4
A Zufälliges Objekt basierend auf Wahrscheinlichkeiten bekommen. Java Basics - Anfänger-Themen 4
A jar File kleiner bekommen Java Basics - Anfänger-Themen 3
B ID von unterschiedlichen Objekten bekommen? Java Basics - Anfänger-Themen 2
B Geocoding Information bekommen (Längen -/ Breitengrad) Java Basics - Anfänger-Themen 9
B API für Längen und Breitengrad zu bekommen Java Basics - Anfänger-Themen 2
L Variablen Parameter bekommen Java Basics - Anfänger-Themen 13
B Jeweils den Parent bekommen -> mehrere Ebenen Java Basics - Anfänger-Themen 2
B Webservice -> alle parameter bekommen von form Java Basics - Anfänger-Themen 2
DaCrazyJavaExpert Threads Klicks pro Sekunde parallel zum Programm bekommen Java Basics - Anfänger-Themen 5
T Extrahiertes Objekt durch Getter bekommen Java Basics - Anfänger-Themen 2
U Filetype bekommen Java Basics - Anfänger-Themen 12
J GridPane per Maus Zelle bekommen, wie? Java Basics - Anfänger-Themen 4
B Registry Key bekommen Java Basics - Anfänger-Themen 1
B MySQL Path bekommen Java Basics - Anfänger-Themen 40
B "Vor" Verzeichnis bekommen Java Basics - Anfänger-Themen 1
B Alle Attribute von Klasse bekommen und ändern Java Basics - Anfänger-Themen 12
B Dateityp von File bekommen Java Basics - Anfänger-Themen 2
M Exception soll Werte mitgeliefert bekommen Java Basics - Anfänger-Themen 12
K Methoden String aus Anführungszeichen bekommen Java Basics - Anfänger-Themen 3
I Locale (bspw. de_DE) bekommen von Locale.getISOCountries Java Basics - Anfänger-Themen 0
D Interface namen bekommen Java Basics - Anfänger-Themen 3
O Auflösung einer Bild-Datei bekommen ohne sie herunterzuladen?? Java Basics - Anfänger-Themen 7
P Element aus einer einelementigen Menge bekommen. Java Basics - Anfänger-Themen 8
W Klassen Kann eine Variable nicht aus einer Klasse bekommen Java Basics - Anfänger-Themen 9
L Webservice soll InputStream übergeben bekommen Java Basics - Anfänger-Themen 7
A Problem: Datums-String in int[] zu bekommen Java Basics - Anfänger-Themen 11
E Objekt bekommen, welches die Methode aufruft? Java Basics - Anfänger-Themen 15
I Nummern/Text aus String bekommen Java Basics - Anfänger-Themen 21
M Java URLConnection schneller bekommen Java Basics - Anfänger-Themen 3
I Aus einem String Vorname & Nachname bekommen Java Basics - Anfänger-Themen 2
M Informationen von externem Programm bekommen (Firefox) Java Basics - Anfänger-Themen 6
C BlueJ zum Laufen bekommen Java Basics - Anfänger-Themen 14
N Koordinaten aus Area bekommen? Java Basics - Anfänger-Themen 3
I Einzelnes Objekt einer Klasse bekommen Java Basics - Anfänger-Themen 9
K Datentypen Klassenname per String angeben und .class bekommen Java Basics - Anfänger-Themen 6
B Ersten Eintrag aus einer Map bekommen Java Basics - Anfänger-Themen 11
D JButton transparent bekommen? Java Basics - Anfänger-Themen 5
R URL eines Jar bekommen? Java Basics - Anfänger-Themen 5
B vorletzten Wert aus einer Reihe bekommen Java Basics - Anfänger-Themen 6
DStrohma Index einer markierten Zeile aus einer JList bekommen? Java Basics - Anfänger-Themen 5
O DocumentListener -> Name des JTextFields bekommen Java Basics - Anfänger-Themen 2
N Mit MouseEvent und JComponent Elementnamen bekommen Java Basics - Anfänger-Themen 5
G Datenbank über Nummer, Daten bekommen Java Basics - Anfänger-Themen 4
G wurzel durch probieren in einer schleife bekommen Java Basics - Anfänger-Themen 5
S Aktuelle Zeile bekommen Java Basics - Anfänger-Themen 2
S Woher Packages bekommen? Wie installieren? (Netbeans) Java Basics - Anfänger-Themen 4
L Inhalt eines Textfeldes bekommen Java Basics - Anfänger-Themen 3
M parent process in die Hand bekommen Java Basics - Anfänger-Themen 2
L Objekt wieder aus einem Vector bekommen! Java Basics - Anfänger-Themen 14
L Model einer Table bekommen Java Basics - Anfänger-Themen 6
R Farbwert bekommen Java Basics - Anfänger-Themen 11

Ähnliche Java Themen

Neue Themen


Oben