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

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?
 
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...
 
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...)
 
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...
 
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?
 
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?
 
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

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:
Ok, aber wo gehst du mit den Bedingungen des Schedules herein?
Die Zeit wird gar nicht beachtet?
ONLY_BETWEEN und SPECIFIC_TIME ?
 
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:
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 ....
 
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?
 
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?
 
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.
 
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....
 
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
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben