This is an algorithm that takes in an ArrayList
of objects that store information on meeting/event schedules. This algorithm's purpose is to check and see what the user's status is based on their current time.
The case scenarios are:
- The user's current time is before all meetings
- The user's current time is during a meeting (also handles meetings that start right when another meeting ends, also if the user is during the final meeting edge case).
- The user's current time is between two meetings
- The user's current time is after all meetings
- There is no meeting data.
After the algorithm determines which case scenario the user is in. It then assigns another object's "Availibility" times.
For instance, if a user's current time is found to be during an already existent meeting for that particular room. Then the "next available start time" for that room becomes the meeting's end time. And the 'next available end time" (i.e. when that room becomes busy again) is assigned to the beginning next meeting after the meeting that the current user's time is in the middle of. Handling of course edge cases like if two meetings immediately follow one another etc etc.
Here is the relevant code:
/**
* Method used by the MeetingDataTest test suite to check different time scenarios.
*/
public void testSetDefaultNextAvailable(ArrayList<MeetingData> testMeetingData, DateTime caseToTest) {
this.meetingData = testMeetingData;
availableNow = false;
DateTime now = caseToTest;
//First check to see if there even are any meetings.
if (meetingData.size()!=0) {
//Check to see if there are meetings, if the user's current time/simulated time is before all meetings.
if (checkIfMorning(now)) {
System.out.println(nextAvailableStart.toString("H:mm a"));
if (nextAvailableEnd != null) {
System.out.println(nextAvailableEnd.toString("H:mm a"));
}
}
//If the user's current time is not found to be before all meetings, next try to see if it is during any meetings.
else if (checkIfDuringMeeting(now)) {
System.out.println(nextAvailableStart.toString("H:mm a"));
if (nextAvailableEnd != null) {
System.out.println(nextAvailableEnd.toString("H:mm a"));
}
}
//If the user's current time is not found to be during any meetings either, next try to see if it is between any two meetings.
else if (checkIfBetweenMeetings(now)) {
System.out.println(nextAvailableStart.toString("H:mm a"));
if (nextAvailableEnd != null) {
System.out.println(nextAvailableEnd.toString("H:mm a"));
}
}
//If the user is not between two meetings either, check to see if they are after all meetings.
else if (checkIfAfterAllMeetings(now)) {
System.out.println(nextAvailableStart.toString("H:mm a"));
if (nextAvailableEnd != null) {
System.out.println(nextAvailableEnd.toString("H:mm a"));
}
}
}
//No meeting data at all, the room is available all day!
else {
availableNow = true;
nextAvailableEnd = new DateTime(now.getYear(), now.getMonthOfYear(), now.getDayOfMonth(), 22, 00, 00, DateTimeZone.getDefault());
nextAvailableStart = now;
System.out.println("Available all day");
}
}
public boolean checkIfAfterAllMeetings(DateTime currentTime) {
boolean isAfterAllMeetings = false;
if (currentTime.isAfter(meetingData.get(meetingData.size() - 1).getEndTime())) {
isAfterAllMeetings = true;
availableNow=true;
nextAvailableStart = currentTime;
//Set to 10:00 PM if no match found
nextAvailableEnd = new DateTime(currentTime.getYear(), currentTime.getMonthOfYear(), currentTime.getDayOfMonth(), 22, 00, 00, DateTimeZone.getDefault());
}
return isAfterAllMeetings;
}
/**
* Checks to see if the user's current time or simulated time is between any two meetings.
* Also sets the availableNow flag to true.
*
* @param currentTime
* @return - True if the user's current time is between two meetings. False if not.
*/
public boolean checkIfBetweenMeetings(DateTime currentTime) {
boolean isBetweenMeetings = false;
loop:
for (int i = 0; i < meetingData.size() - 1; i++) {
if (currentTime.isBefore(meetingData.get(i + 1).getStartTime()) && currentTime.isAfter(meetingData.get(i).getEndTime())) {
isBetweenMeetings = true;
availableNow = true;
nextAvailableStart = currentTime;
nextAvailableEnd = meetingData.get(i + 1).getStartTime();
}
}
return isBetweenMeetings;
}
/**
* Checks to see if the user is before all meetings. If so, sets the time availability to now, enables the "availableNow" boolean flag
* and then sets the end time availability for the beginning/start time of the first meeting.
*
* @param currentTime - the current time, simulated or actual.
* @return - True if the user's current time/simulated time is before any meetings. False if not.
*/
public boolean checkIfMorning(DateTime currentTime) {
boolean isBeforeAllMeetings = false;
loop:
for (int i = 0; i < meetingData.size() - 1; i++) {
//case 1 - user is before any meetings.
if (currentTime.isBefore(meetingData.get(0).getStartTime())) {
nextAvailableStart = currentTime;
nextAvailableEnd = meetingData.get(0).getStartTime();
// Log.v("Case 1", nextAvailableEnd.toString("HH:mm a"));
availableNow = true;
isBeforeAllMeetings = true;
break loop;
}
}
return isBeforeAllMeetings;
}
/**
* Checks to see if the user's current time is during a meeting. If it is it sets the corresponding next availabilities.
* Also handles the caveat that the user is during the "final meeting of the day" and if that is the case, it sets the next available
* start time to the final meeting's end time and the next available end time gets hard coded to 10:00 PM of the current day.
* NOTE - This also handles meetings that are immediately followed by another meeting.
*
* @param currentTime - the current time, simulated or actual.
* @return - True if the user's current time/simulated time is during any meetings. False if not.
*/
public boolean checkIfDuringMeeting(DateTime currentTime) {
boolean isDuringMeeting = false;
boolean isDuringFinalMeeting = false;
MeetingData referenceMeeting = null;
int indexOfFoundMeeting = 0;
//SET THE REFERENCE POINT
findMeetingThatTheCurrentTimeIsDuring:
for (int i = 0; i < meetingData.size(); i++) {
if (currentTime.isAfter(meetingData.get(i).getStartTime()) && currentTime.isBefore(meetingData.get(i).getEndTime())) {
referenceMeeting = meetingData.get(i);
indexOfFoundMeeting = i;
isDuringMeeting = true;
if (i == meetingData.size() - 1) {
isDuringFinalMeeting = true;
}
break findMeetingThatTheCurrentTimeIsDuring;
}
}
if (isDuringMeeting && !isDuringFinalMeeting) {
loopFindNextAvailabilitiesUsingReferenceMeeting:
for (int i = indexOfFoundMeeting + 1; i < meetingData.size() - 1; i++) {
if (!referenceMeeting.getEndTime().isBefore(meetingData.get(i).getStartTime()) || referenceMeeting.getEndTime().isEqual(meetingData.get(i).getStartTime())) {
referenceMeeting = meetingData.get(i);
nextAvailableStart = referenceMeeting.getEndTime();
nextAvailableEnd = meetingData.get(i + 1).getStartTime();
}
}
} else if (isDuringFinalMeeting) {
//Set to 10:00 PM if no match found
nextAvailableEnd = new DateTime(currentTime.getYear(), currentTime.getMonthOfYear(), currentTime.getDayOfMonth(), 22, 00, 00, DateTimeZone.getDefault());
nextAvailableStart = referenceMeeting.getEndTime();
}
return isDuringMeeting;
}
Useful background info:
- This is using
JodaTime
library for time comparisons. - Incoming
RoomData
andMeetingData
is parsed fromJSON
and constructed into anArrayList
.
What I'd like to improve on or receive feedback on:
- Better way to write algorithms if possible instead of nesting for-loops.
- Comments about code format
- Anything else really.